【问题标题】:Matching on namespace during xsl transform在 xsl 转换期间匹配命名空间
【发布时间】:2015-11-28 11:34:00
【问题描述】:

我有一个文档,其中根元素定义了一个命名空间,当我编写一个 xsl 进行转换时,我没有看到任何匹配的元素。

<xsl:stylesheet version="2.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="node()|@*">
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="//supplydetail/price"/>

</xsl:stylesheet>

XML 文件如下所示:

<?xml version="1.0" encoding="iso-8859-1"?>
<ONIXmessage xmlns="http://www.editeur.org/onix/2.1/short">
  <header>
    <m173>2012086</m173>
    <m174>foobar</m174>
  </header>
  <product>
    <supplydetail>
        <j137>Foo Bar</j137>
        <j396>20</j396>
        <price>
            <j148>42</j148>
            <j151>5.99</j151>
            <j152>AUD</j152>
            <b251>AU</b251>
        </price>
    </supplydetail>
  </product>
</ONIXmessage>

我看到的是我的supplydetail/price 元素根本不匹配,即使它存在于/ONIXmessage/product/supplydetail/price 的文档中

我尝试在 xsl 中指定从 root 开始的完整路径,但这也不起作用。我得到的输出是输入的直接副本,我期望的是输入的副本,除了价格元素。我认为原因是输入 XML 的 ONIXmessage 元素中的命名空间声明,但我如何在 xsl.xml 中指定它。

谢谢

【问题讨论】:

  • 这个问题已经被问了几百次了,也有很多好的答案。要找到适合您需要的名称,请在 XSLT 的上下文中搜索 default namespace,例如stackoverflow.com/q/1344158/1987598.
  • Mathias,感谢您的回复,我的问题是我无法以返回您提到的链接的方式提出问题。

标签: xslt xpath xml-namespaces onix


【解决方案1】:

我同意Matthias Müller 经常问这个问题,但我不同意再次问这个问题是错误的。您可能已经尝试找到解决方案,但未能理解或应用您发现的内容。

可以在 Understanding XML NamespacesNamespaces in XSLT 上找到一篇关于该主题的优秀的介绍性和深入的论文,两者均由 Evan Lenz 撰写。如果您想对 XML 和 XSLT 做任何有用的事情,我真的建议您花点时间阅读这篇文章。

底线是:在 XSLT 中声明命名空间,通常在顶部 xsl:stylesheet 元素中,并在 XPath 表达式中使用这些命名空间:

<xsl:stylesheet version="2.0"
    xmlns:onix="http://www.editeur.org/onix/2.1/short"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="node()|@*">
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="//onix:supplydetail/onix:price"/>

</xsl:stylesheet>

由于您使用的是 XSLT 2.0,因此您可以使用 xpath-default-namespace,它设置用于 XPath 表达式和模式中无前缀节点测试的命名空间:

<xsl:stylesheet version="2.0"
    xpath-default-namespace="http://www.editeur.org/onix/2.1/short"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

要获得用于文字结果元素的相同名称空间,请在这些名称前加上已声明的名称空间,或将默认名称空间设置为指向您选择的名称空间(在您当前的代码中,没有文字结果元素) .

如果您事先不知道实际的命名空间,但您知道本地名称,请使用*:supplydetail 之类的匹配模式,但这有在另一个命名空间中也匹配相同名称的风险;如果你能避免它,你应该这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    相关资源
    最近更新 更多