存在xmlns属性时如何使用XSLT?

时间:2019-02-14 18:28:15

标签: xml csv xslt

我正在尝试使用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>&#xA;</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>&#xA;</xsl:text> <!-- Works -->

    <xsl:for-each select="*[local-name() = 'c/d']"> <!-- Does not work -->
        <xsl:value-of select="."/>
        <xsl:text>&#xA;</xsl:text>
    </xsl:for-each>

</xsl:template>
</xsl:stylesheet>

但是,如果注释指示for-for根本不匹配,则仅显示“ B”。

我无法更改XML。从理论上讲,我可以使用sed或其他方法删除xmlns属性,但是理想情况下我想避免这种情况,因为输入XML文件的大小为数GB。

当存在xmlns属性时,如何使我的简化代码起作用?

1 个答案:

答案 0 :(得分:2)

您需要在xslt中声明默认名称空间。看到这个:

XSLT with XML source that has a default namespace set to xmlns