查找与context元素相关的标准的直接兄弟姐妹

时间:2012-06-23 05:23:51

标签: xpath

我有XML结构。 执行XPath的上下文是类属性为“ac”的元素之一。帮我编写XPath,找到属性类为“ac1”的上下文元素的所有直接兄弟。例如。如果执行的上下文是具有类属性“ac”的第二个元素,则结果应包含两个(而不是三个)具有类属性“ac1”的立即元素。

谢谢。

<container>
<item class="ac"/>
<item class="ac1"/>
<item class="ac1"/>
<item class="ac1"/>
<item class="ac"/>
<item class="ac1"/>
<item class="ac1"/>
<item class="ac2"/>
<item class="ac1"/>
<item class="ac"/>
<item class="ac1"/>
<item class="ac1"/>
<item class="ac1"/>
</container>

1 个答案:

答案 0 :(得分:1)

<强>予。在XPath 1.0中,将Kayessian方法用于两个节点集的交集:

$ns1[count(.|$ns2) = count($ns2)]

这将选择两个节点集$ns1$ns2的交集。

替换

$ns1

/*/*[@class='ac'][1]/following-sibling::*[@class='ac1']

$ns2

/*/*[@class='ac'][2]
        /following-sibling::*[not(@class='ac1')][3]
                                  /preceding-sibling::*

生成的XPath表达式为

 /*/*[@class='ac'][4]
         /following-sibling::*[@class='ac1']
           [count(.
                 |
                  /*/*[@class='ac'][5]
                       /following-sibling::*[not(@class='ac1')][6]
                                              /preceding-sibling::*
                  )
           =
            count(/*/*[@class='ac'][7]
                       /following-sibling::*[not(@class='ac1')][8]
                                              /preceding-sibling::*
                  )
         ]

基于XSLT的验证

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

 <xsl:variable name="ns1" select=
  "/*/*[@class='ac'][9]/following-sibling::*[@class='ac1']"/>

 <xsl:variable name="ns2" select=
  "/*/*[@class='ac'][10]
        /following-sibling::*[not(@class='ac1')][11]
                                  /preceding-sibling::*"/>

 <xsl:template match="/">
   <xsl:copy-of select=
   "$ns1[count(.|$ns2) = count($ns2)]"/>
=========
   <xsl:copy-of select=
   "/*/*[@class='ac'][12]
         /following-sibling::*[@class='ac1']
           [count(.
                 |
                  /*/*[@class='ac'][13]
                       /following-sibling::*[not(@class='ac1')][14]
                                              /preceding-sibling::*
                  )
           =
            count(/*/*[@class='ac'][15]
                       /following-sibling::*[not(@class='ac1')][16]
                                              /preceding-sibling::*
                  )
         ]
   "/>
 </xsl:template>
</xsl:stylesheet>

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

<container>
    <item class="ac"/>
    <item class="ac1"/>
    <item class="ac1"/>
    <item class="ac1"/>
    <item class="ac"/>
    <item class="ac1"/>
    <item class="ac1"/>
    <item class="ac2"/>
    <item class="ac1"/>
    <item class="ac"/>
    <item class="ac1"/>
    <item class="ac1"/>
    <item class="ac1"/>
</container>

评估两个XPath表达式(一个包含变量,另一个包含变量),并将每个表达式的选定节点复制到输出

<item class="ac1"/>
<item class="ac1"/>
=========
   <item class="ac1"/>
<item class="ac1"/>

<强> II。 XPath 2.0解决方案:

只需使用标准的XPath 2.0 intersect 运算符和相同的两个节点集。

或者,可以使用标准运算符 << >>