2

我有这个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 属性的节点。

4

2 回答 2

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>
于 2012-05-11T20:22:33.677 回答
3

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

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

说明

这是“双重否定原则”的一个简单而具体的案例:)

基于 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>
于 2012-05-12T03:55:40.057 回答