Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html 使用XPath在两个节点之间选择同级_Html_Xpath - Fatal编程技术网

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

Html 使用XPath在两个节点之间选择同级,html,xpath,Html,Xpath,如何选择id为header_completed的表和header_completed后的第一个表之间的所有表,即中间对齐的表?以下是我从中选择的html: <table border="0" cellpadding="0" cellspacing="0" width="920" align="center"></table> <table border="0" cellpadding="0" cellspacing="0" width="920"></t

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

<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>


使用节点集相交的Kayesian方法

<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>
<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>
<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"/>
两个节点集
$ns1
$ns2
的交集由以下XPath表达式计算:

$ns1[count(.| $ns2)=count($ns2)]
<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文档

<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>
<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>
<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"/>
$ns2
是:

/*/*[@class='header_completed'][1]
                     /following-sibling::*
/*/*[@class='header_completed'][1]
             /following-sibling::*[@align='center'][1]
                   /preceding-sibling::*
我们只需在Kayessian公式中替换
$ns1
$ns2
,即可得到以下XPath表达式,该表达式正好选择所需的5个元素:

/*/*[@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::*)
              ]
为了验证这是真正的解决方案,我们使用以下XSLT转换:

<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>
<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>
<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"/>
下面是一个XSLT 2.0解决方案,证明了此XSLT 2.0表达式的正确性:

$ns1[count(.| $ns2)=count($ns2)]
<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文档时,我们再次得到了相同的正确结果:

<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表达式会选择您想要的节点:

//table[@class="header_completed"]/
    following-sibling::table[@align="center"][1]/
        preceding-sibling::table[
            preceding-sibling::table[@class="header_completed"]
        ]
首先,我使用
@class=“header\u completed”
导航到

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


从那里,我选择所有前面的同级表,这些表都有一个前面的同级表,即带有
@class=“header\u completed”

好问题(+1)的表。请看我的答案以获得解释和完整的解决方案。该死,你真的尽了最大努力去问一个好的棘手问题。关于实用性和鲁棒性设计的完整要点,我非常想将其扩展到
[@class='header\u completed']
…一些节点的两个实例…
[@align='center']
,并一次性捕获这两个集合。+1用于实际可行的解决方案,无需硬编码位置,思维良好。然而,在扩展它之后,我想知道你是否会对我在对问题的评论中提出的可能性有任何见解:如果我们在节点之间有两个有效的序列会怎么样,即:如果我们在自身之后复制示例,如何仍然得到10个结果节点(在
match1\u of u start
match1\u of u end
+
match2\u of u start
match2\u of u end
)之间,而不是整个列表(在
match1\u of u start
match2\u of u end
).+1这是一个很好的解决方案,也很容易理解。非常感谢。@Wrikken这肯定是一个挑战。我必须考虑这个问题。+1这是一个非常有洞察力的答案,也是一个非常有用的答案。它有很好的解释和证明。谢谢。+1这是这个问题的实际答案,也是凯西公式A的一个有指导意义的例子应用程序也是如此。