在将命名空间添加到xml时,使用xslt解析xml失败

时间:2011-10-17 14:20:17

标签: xml xslt namespaces transform

我有以下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的top元素时,它无法找到xml元素。我在这个网站上看到了一些相关的问题,但仍然没有弄清楚如何解决我的具体问题。我尝试按照建议的here添加doc:但它没有帮助。也许是因为我正在使用//?还有其他方法可以进行这些查询吗?

还有其他建议如何解决这个问题?

1 个答案:

答案 0 :(得分:4)

这是最大的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表达式必须包含带前缀的名称,并且前缀必须与默认名称空间相关联 - 如上面的解决方案中所做的那样。