抛出处理器错误的XSLT名称空间前缀

时间:2013-04-02 20:21:53

标签: xml xslt

我正在尝试组合一些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:名称空间前缀,这有效(至少,它出现在结果文档中),但是尽管如此,处理器仍会抛出一堆警告{{1是一个无效的元素名称...尽管事实上元素名称实际上在输出中正确地结束为sbn:

还有其他办法吗?我不想在每个元素上都有sbn:fieldName属性。我使用Oxygen和Saxon6.5.5作为处理器,虽然我在我尝试的其他所有处理器上都遇到了同样的错误(Xalan和libxslt Mac命令行版本)。

(你可能会问:如果输出正常,我为什么要关心?好问题!我现在正在Oxygen中的一个小文件上运行转换,但目标是转换百万行XML文件并做它来自命令行使用xmlns,因此我没有Oxygen的内存开销,因为我需要所有内存来运行转换。)

修改:更多详情。

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

xsltproc

还有样式表的精简版,显示了问题。

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

这给出了xsltproc错误:<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>

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

name()函数返回节点的名称及其前缀,因此在这种情况下sbn:{name()}正在评估sbn:sbn:fieldName。相反,你应该使用它,如果你想确保在输出中使用前缀sbn:

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

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

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

<xsl:copy>
  <!-- (Whatever content you want) -->
</xsl:copy>