需要帮助xpath

时间:2012-05-11 20:12:19

标签: xml xpath

我有这个xml:

    <mappings>      
        <mapping>       
           <name iskey="true">234</name>     
           <aid iskey="true">bmz</aid>    
           <bid iskey="true">sim</bid>    
           <data>GSSS</data>     
        </mapping>     
        <mapping>     
          <aid iskey="true">bmz</aid>     
          <bid iskey="true">sim</bid>    
          <data>TS</data>    
        </mapping>    
        <mapping>    
          <aid iskey="true">bmz</aid>
          <account>TS</account>     
        </mapping> 
     </mappings> 
  

我需要xpath来选择具有节点<aid iskey='true'>bmz</aid>的节点,而不需要包含iskey属性的其他节点。

2 个答案:

答案 0 :(得分:4)

在评论中来回几次后,您似乎希望获得mapping节点(或任何其他节点)的aid子节点某些属性和值但没有其他具有@iskey属性的子节点。你这样做:

//*[aid/@iskey='true' and aid/text()='bmz'][not(*[@iskey][local-name() != 'aid'])]

谓词恰恰说明了:aid子节点具有这些值,并且没有aid以外的名称的子节点碰巧有@iskey属性。

当我运行这个简单的测试样式表时:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:template match="/">
        <xsl:copy-of select="//*[aid/@iskey='true' and aid/text()='bmz'][not(*[@iskey][local-name() != 'aid'])]"/>
    </xsl:template> 
</xsl:stylesheet>
输入文档上的

我得到以下信息:

<mapping>
    <aid iskey="true">bmz</aid>   <!-- I need this node -->
    <account>TS</account>
</mapping>

更新如果您希望获得只有一个@iskey子节点的节点,您可以放弃:

//*[count(*[@iskey]) = 1]

我将它插入我的测试样式表中,它产生了相同的预期结果:

<mapping>
    <aid iskey="true">bmz</aid>   <!-- I need this node -->
    <account>TS</account>
</mapping>

答案 1 :(得分:3)

使用这个更短更简单的XPath表达式

   /*/*
     [aid[@iskey='true' and .='bmz']
    and
      not(*[not(self::aid)][@iskey])
      ]

<强>解释

这是一个简单,具体的“ Double Negation Principle ”案例:)

基于XSLT的验证:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "/*/*
     [aid[@iskey='true' and .='bmz']
    and
      not(*[not(self::aid)][@iskey])
      ]"/>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<mappings>
    <mapping>
        <name iskey="true">234</name>
        <aid iskey="true">bmz</aid>
        <bid iskey="true">sim</bid>
        <data>GSSS</data>
    </mapping>
    <mapping>
        <aid iskey="true">bmz</aid>
        <bid iskey="true">sim</bid>
        <data>TS</data>
    </mapping>
    <mapping>
        <aid iskey="true">bmz</aid>
        <account>TS</account>
    </mapping>
</mappings>

评估XPath表达式并将所选元素(本例中只有一个)复制到输出

<mapping>
   <aid iskey="true">bmz</aid>
   <account>TS</account>
</mapping>