我正在尝试组合一些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>
答案 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>