我正在尝试使用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-for根本不匹配,则仅显示“ B”。
我无法更改XML。从理论上讲,我可以使用sed或其他方法删除xmlns属性,但是理想情况下我想避免这种情况,因为输入XML文件的大小为数GB。
当存在xmlns属性时,如何使我的简化代码起作用?
答案 0 :(得分:2)
您需要在xslt中声明默认名称空间。看到这个:
XSLT with XML source that has a default namespace set to xmlns