Selecting siblings between two nodes using XPath

前端 未结 2 1578
梦毁少年i
梦毁少年i 2020-12-02 11:49

How would I select all the tables between the table whose id is header_completed and the first table after the header_completed one that has an align of center? Here is the

2条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-02 11:50

    Use the Kayessian method of node-set intersection:

    The intersection of two node-sets $ns1 and $ns2 is evaluated by the following XPath expression:

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

    If we have the following XML document:

    
        

    then according to the question, we have:

    $ns1 is:

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

    $ns2 is:

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

    We simply substitute $ns1 and $ns2 in the Kayessian formula and get the following XPath expression, which selects exactly the wanted 5 elements:

    /*/*[@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::*)
                  ]
    

    To verify that this is really the solution, we use this XSLT transformation:

    
     
    
     
        
    
        
            
            
            
        
    
    

    When this transformation is applied on the XML document above, the wanted correct result is produced:

    XPath 2.0 solution:

    In XPath 2.0 we can use the intersect operator and the >> and/or the << operators.

    The XPath 2.0 expression that corresponds to the previously used XPath 1.0 expression is:

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

    Here is an XSLT 2.0 solution, proving the correctness of this XSLT 2.0 expression:

    
     
    
     
    
        
    
     
       
      
       
     
    
    

    when applied on the XML document defined before, we again get the same wanted, correct result:

    提交回复
    热议问题