首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用XPath在两个节点之间选择同级节点

使用XPath在两个节点之间选择同级节点
EN

Stack Overflow用户
提问于 2010-08-07 05:58:44
回答 2查看 16K关注 0票数 34

如何选择id为header_completed的表和header_completed表之后对齐为中心的第一个表之间的所有表?下面是我从中选择它的html:

代码语言:javascript
复制
<table border="0" cellpadding="0" cellspacing="0" width="920" align="center"></table>
<table border="0" cellpadding="0" cellspacing="0" width="920"></table>
<table border="0" cellpadding="0" cellspacing="0" width="920"></table>
<table border="0" cellpadding="0" cellspacing="0" width="920" align="center" class="header_completed"></table>
<table border="0" cellpadding="0" cellspacing="0" width="920"></table> <--          -->
<table border="0" cellpadding="0" cellspacing="0" width="920"></table> <--          -->
<table border="0" cellpadding="0" cellspacing="0" width="920"></table> <-- these 5  -->
<table border="0" cellpadding="0" cellspacing="0" width="920"></table> <--          -->
<table border="0" cellpadding="0" cellspacing="0" width="920"></table> <--          -->
<table border="0" cellpadding="0" cellspacing="0" width="920" align="center"></table>
<table border="0" cellpadding="0" cellspacing="0" width="920"></table>
<table border="0" cellpadding="0" cellspacing="0" width="920"></table>
<table border="0" cellpadding="0" cellspacing="0" width="920" align="center"></table>

我试过使用//table[@id="header_completed"]/following-sibling::node()[following-sibling::table[@align="center"][1]],但它不起作用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-08-07 07:12:03

我相信这个XPath表达式会选择您想要的节点:

代码语言:javascript
复制
//table[@class="header_completed"]/
    following-sibling::table[@align="center"][1]/
        preceding-sibling::table[
            preceding-sibling::table[@class="header_completed"]
        ]

首先,我使用@class="header_completed"导航到table

从那里,我用@align="center"选择了下面的第一个同级表。

从那里,我选择所有前面的同级表,这些表都有一个前面的同级表,即带有@class="header_completed"的表。

票数 37
EN

Stack Overflow用户

发布于 2010-08-07 06:30:34

使用节点集相交的Kayessian方法

$ns1 $ns2 的两个节点集的交集是通过以下XPath表达式求值的:

代码语言:javascript
复制
$ns1[count(.| $ns2)=count($ns2)]

如果我们有以下XML文档,则为

代码语言:javascript
复制
<t>
    <table border="0" cellpadding="0" cellspacing="0" width="920" align="center"></table>
    <table border="0" cellpadding="0" cellspacing="0" width="920"></table>
    <table border="0" cellpadding="0" cellspacing="0" width="920"></table>
    <table border="0" cellpadding="0" cellspacing="0" width="920" align="center" class="header_completed"></table>
    <table border="0" cellpadding="0" cellspacing="1" width="920"></table>
    <table border="0" cellpadding="0" cellspacing="2" width="920"></table>
    <table border="0" cellpadding="0" cellspacing="3" width="920"></table>
    <table border="0" cellpadding="0" cellspacing="4" width="920"></table>
    <table border="0" cellpadding="0" cellspacing="5" width="920"></table>
    <table border="0" cellpadding="0" cellspacing="0" width="920" align="center"></table>
    <table border="0" cellpadding="0" cellspacing="0" width="920"></table>
    <table border="0" cellpadding="0" cellspacing="0" width="920"></table>
    <table border="0" cellpadding="0" cellspacing="0" width="920" align="center"></table>
</t>

然后根据问题,我们有

$ns1是:

代码语言:javascript
复制
/*/*[@class='header_completed'][1]
                     /following-sibling::*

$ns2是:

代码语言:javascript
复制
/*/*[@class='header_completed'][1]
             /following-sibling::*[@align='center'][1]
                   /preceding-sibling::*

我们只需替换Kayessian公式中的$ns1$ns2,并获得以下XPath表达式,它准确地选择了所需的5个元素:

代码语言:javascript
复制
/*/*[@class='header_completed'][1]
                         /following-sibling::*
              [count(.|/*/*[@class='header_completed'][1]
                            /following-sibling::*[@align='center'][1]
                               /preceding-sibling::*)
              =
               count(/*/*[@class='header_completed'][1]
                            /following-sibling::*[@align='center'][1]
                                /preceding-sibling::*)
              ]

为了验证这就是解决方案,我们使用这个转换

代码语言:javascript
复制
<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='header_completed'][1]
                         /following-sibling::*
      "/>
    <xsl:variable name="ns2" select=
       "/*/*[@class='header_completed'][1]
                 /following-sibling::*[@align='center'][1]
                       /preceding-sibling::*
       "/>

    <xsl:template match="/">
        <xsl:copy-of select=
       "$ns1[count(.| $ns2)=count($ns2)]
       "/>
        <DELIMITER/>
        <xsl:copy-of select=
       "/*/*[@class='header_completed'][1]
                         /following-sibling::*
              [count(.|/*/*[@class='header_completed'][1]
                            /following-sibling::*[@align='center'][1]
                               /preceding-sibling::*)
              =
               count(/*/*[@class='header_completed'][1]
                            /following-sibling::*[@align='center'][1]
                                /preceding-sibling::*)
              ]
       "/>
    </xsl:template>
</xsl:stylesheet>

当对上面的XML文档应用此转换时,将生成所需的正确结果

代码语言:javascript
复制
<table border="0" cellpadding="0" cellspacing="1" width="920"/>
<table border="0" cellpadding="0" cellspacing="2" width="920"/>
<table border="0" cellpadding="0" cellspacing="3" width="920"/>
<table border="0" cellpadding="0" cellspacing="4" width="920"/>
<table border="0" cellpadding="0" cellspacing="5" width="920"/>
<DELIMITER/>
<table border="0" cellpadding="0" cellspacing="1" width="920"/>
<table border="0" cellpadding="0" cellspacing="2" width="920"/>
<table border="0" cellpadding="0" cellspacing="3" width="920"/>
<table border="0" cellpadding="0" cellspacing="4" width="920"/>
<table border="0" cellpadding="0" cellspacing="5" width="920"/>

XPath 2.0解决方案

在XPath 2.0中,我们可以使用intersect运算符以及>>和/或<<运算符。

与先前使用的XPath 1.0表达式相对应的XPath 2.0表达式为:

代码语言:javascript
复制
     /*/*[ .
        >>
         /*/*[@class='header_completed'][1]
         ]

  intersect

    /*/*[ /*/*[@class='header_completed'][1]
                 /following-sibling::*[@align='center'][1]
             >>
              .
        ]

下面是一个XSLT 2.0解决方案,它证明了这个XSLT 2.0表达式的正确性:

代码语言:javascript
复制
<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="ns1" select=
  "/*/*[ .
        >>
         /*/*[@class='header_completed'][1]
       ]
  "/>

    <xsl:variable name="ns2" select=
       "/*/*[ /*/*[@class='header_completed'][1]
                 /following-sibling::*[@align='center'][1]
             >>
              .
             ]
       "/>

 <xsl:template match="/">
   <xsl:sequence select="$ns1 intersect $ns2"/>
  <DELIMITER/>
   <xsl:sequence select=
   "/*/*[ .
        >>
         /*/*[@class='header_completed'][1]
       ]

  intersect

    /*/*[ /*/*[@class='header_completed'][1]
                 /following-sibling::*[@align='center'][1]
             >>
              .
        ]
   "/>
 </xsl:template>
</xsl:stylesheet>

当应用于前面定义的XML文档时,我们再次获得相同的、正确的结果:

代码语言:javascript
复制
<table border="0" cellpadding="0" cellspacing="1" width="920"/>
<table border="0" cellpadding="0" cellspacing="2" width="920"/>
<table border="0" cellpadding="0" cellspacing="3" width="920"/>
<table border="0" cellpadding="0" cellspacing="4" width="920"/>
<table border="0" cellpadding="0" cellspacing="5" width="920"/>
<DELIMITER/>
<table border="0" cellpadding="0" cellspacing="1" width="920"/>
<table border="0" cellpadding="0" cellspacing="2" width="920"/>
<table border="0" cellpadding="0" cellspacing="3" width="920"/>
<table border="0" cellpadding="0" cellspacing="4" width="920"/>
<table border="0" cellpadding="0" cellspacing="5" width="920"/>
票数 32
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3428104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档