1

我正在尝试组合一些 XML 文件并将它们之间的命名空间分开,并且遇到了一些问题。我能够在 SO 上找到的所有内容看起来都像这样(XSLT):

<xsl:for-each select="sbn:fieldName">
   <xsl:element name="sbn:{name()}">
      <xsl:value-of select="text()"/>
   </xsl:element>
</xsl:for-each>

我想sbn:在输出中保留命名空间前缀,这有效(至少,它显示在结果文档中),但尽管如此,处理器还是抛出了一堆sbn:无效元素名称的警告......尽管事实上元素名称实际上在输出中正确结束为sbn:fieldName.

还有其他方法可以做到这一点吗?我不想xmlns在每个元素上都有这个属性。我使用 Oxygen 和 Saxon6.5.5 作为处理器,尽管在我尝试过的所有其他处理器(Xalan 和 libxslt Mac 命令行版本)上都会遇到相同的错误。

(你可能会问:如果输出没问题,我为什么要关心?问得好!我现在在 Oxygen 中对一个小文件运行转换,但目标是转换一个百万行的 XML 文件并从使用命令行,xsltproc这样我就没有氧气的内存开销,因为我需要所有我能得到的内存来运行转换。)

编辑:更多细节。

这是我正在尝试处理的文件的精简版本。

<collection xmlns="http://www.example.com/ns/foo">
    <record>
        <fieldName>
            <subA>some text</subA>
            <subB>more text</subB>
        </fieldName>
    </record>
</collection>

以及样式表的精简版本,显示了问题。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:sbn="http://www.example.com/ns/foo"
   xmlns:bar="http://www.example.com/ns/bar"
   version="1.0">

   <xsl:template match="//sbn:record">
    <xsl:for-each select="sbn:fieldName/node()">
       <xsl:element name="sbn:{local-name()}">
          <xsl:value-of select="text()"/>
       </xsl:element>
    </xsl:for-each>
   </xsl:template>

</xsl:stylesheet>

这给出了 xsltproc 错误:runtime error: file tiny.xslt line 8 element element xsl:element: The effective name 'sbn:' is not a valid QName.

4

2 回答 2

1

我认为问题在于您正在使用sbn:fieldName/node()- 它也匹配没有名称的文本节点 - 因此出现错误。

这对我有用:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:sbn="http://www.example.com/ns/foo"
   xmlns:bar="http://www.example.com/ns/bar"
   version="1.0">

   <xsl:template match="//sbn:record">
    <xsl:for-each select="sbn:fieldName/*">
       <xsl:element name="{name()}" namespace="{namespace-uri()}">
          <xsl:value-of select="text()"/>
       </xsl:element>
    </xsl:for-each>
   </xsl:template>

</xsl:stylesheet>
于 2013-04-02T22:28:24.673 回答
0

该函数返回带有前缀name()的节点的名称,因此在这种情况下计算结果为。相反,如果要确保在输出中使用前缀,则应该使用它:sbn:{name()}sbn:sbn:fieldNamesbn:

<xsl:element name="sbn:{local-name()}">

或以下任一项,如果您想重用输入中使用的任何前缀:

<xsl:element name="{name()}">

或者

<xsl:copy>
  <!-- (Whatever content you want) -->
</xsl:copy>
于 2013-04-02T20:46:41.827 回答