【发布时间】:2019-07-08 20:42:47
【问题描述】:
我正在尝试使用 XSLT 将 XML 文档转换为 CSV。我遇到的问题是拥有“xmlns”属性会使某些事情难以处理。
首先,这是一个简单的例子。
XML:
<a>
<b>B</b>
<c>
<d>D1</d>
<d>D2</d>
</c>
</a>
XSL:
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>
<xsl:template match="/a">
<xsl:for-each select="c/d">
<xsl:value-of select="../../b"/>,<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
产生正确的输出
B,D1
B,D2
不过,只需在顶部添加 xmlns 属性
<a xmlns="http://example.com">
<b>B</b>
<c>
<d>D1</d>
<d>D2</d>
</c>
</a>
导致仅打印叶节点内容的默认行为(当没有匹配成功时会发生这种情况),而不是按预期生成 CSV。
我能够像这样获得部分成功
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>
<xsl:template match="*[local-name() = 'a']">
<xsl:value-of select="*[local-name() = 'b']"/><xsl:text>
</xsl:text> <!-- Works -->
<xsl:for-each select="*[local-name() = 'c/d']"> <!-- Does not work -->
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
然而,由于注释表明 for-each 根本不匹配,这只会打印“B”。
我无法更改 XML。理论上我可以使用 sed 或其他东西来删除 xmlns 属性,但我最好避免这种情况,因为输入的 XML 文件有很多 GB。
当存在 xmlns 属性时,如何调整我的简化代码以使其正常工作?
【问题讨论】: