【问题标题】:How to use XSLT when xmlns attribute is present? [duplicate]存在 xmlns 属性时如何使用 XSLT? [复制]
【发布时间】: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>&#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-each 根本不匹配,这只会打印“B”。

我无法更改 XML。理论上我可以使用 sed 或其他东西来删除 xmlns 属性,但我最好避免这种情况,因为输入的 XML 文件有很多 GB。

当存在 xmlns 属性时,如何调整我的简化代码以使其正常工作?

【问题讨论】:

    标签: xml csv xslt


    【解决方案1】:

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

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

    【讨论】:

    • 我读了那个问题,但不知何故没有接受它。感谢您的超快回复,那个问题+解决方案解决了我的问题!
    猜你喜欢
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多