【问题标题】:Parsing xml using xslt fails when adding namespace to xml将命名空间添加到 xml 时使用 xslt 解析 xml 失败
【发布时间】:2011-12-09 08:32:41
【问题描述】:

我有以下 xml 文件:

<DataConfiguration 
  xmlns="http://www.mysite.com/namespace"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.mysite.com/namespace/DataConfiguration.xsd">

  <rule>
    <if>
       ...
    </if>
    <then>
       ...
    </then>
  </rule>

</DataConfiguration>

我想使用以下 xslt 解析:

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:doc="http://www.mysite.com/namespace" 
  exclude-result-prefixes="xsi">

<xsl:output omit-xml-declaration="yes"/>
<xsl:output method="text"/>
<xsl:template match = "/">

<xsl:for-each select="//rule">
  <xsl:for-each select="if/*">
     ...
  </xsl:for-each>
</xsl:for-each>

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

xslt 按预期工作,但是当我将 xmlns 属性添加到 xml 的顶部元素时,它无法找到 xml 元素。我在这个网站上看到了一些相关的问题,但仍然不知道如何解决我的具体问题。我尝试按照建议的here 将 doc: 添加到选择中,但没有帮助。也许是因为我正在使用 // ?还有其他方法可以进行这些查询吗?

还有其他解决方法的建议吗?

【问题讨论】:

    标签: xml xslt namespaces transform


    【解决方案1】:

    这是最大的 XPath XSLT 常见问题解答。只需搜索:"XPath default namespace"

    非常简短

    变化:

    <xsl:for-each select="//rule">   
      <xsl:for-each select="if/*">   
         ...   
      </xsl:for-each>   
    </xsl:for-each> 
    

    收件人:

    <xsl:for-each select="//doc:rule">   
      <xsl:for-each select="doc:if/*">   
         ...   
      </xsl:for-each>   
    </xsl:for-each> 
    

    观察到令人困惑的问题的原因是,在 XPath 中,任何不带前缀的名称都被视为“无命名空间”。

    因此,select="//rule" 不会选择默认命名空间中的文档中的任何元素 -- 没有名为 rule 的元素不在任何命名空间中。

    相反,XPath 表达式必须包含前缀名称,并且前缀必须与默认命名空间相关联——如上述解决方案中所做的那样。

    【讨论】:

    • 感谢您的快速响应,它有效!只是为了添加更多信息,我注意到如果我有包含多个元素的 xpath,我需要为每个元素添加前缀,例如:
    • @Tamir:很高兴我的回答很有用。请考虑按照 SO 既定规则的要求接受它(只需单击您希望接受的答案旁边的复选标记)。
    猜你喜欢
    • 2010-12-22
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 2021-05-03
    • 2014-01-10
    • 1970-01-01
    相关资源
    最近更新 更多