1

我有 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>
4

1 回答 1

1

I. 在 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"/>

二、XPath 2.0 解决方案

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

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

于 2012-06-23T15:58:44.797 回答