代码之家  ›  专栏  ›  技术社区  ›  Kermit

段落后列表项内跨距的xpath

  •  1
  • Kermit  · 技术社区  · 7 年前

    我有以下文件:

    <html>
    <head>
    <title>Page</title>
    </head>
    
    <body>
    
    <div>
        <div>
            <div>
            </div>
            <div class="this one">
                <p><span><strong>Ignore</strong></span></p>
                    <p>Text</p>
                <p><span><strong>Header 1</strong></span></p>
                    <ul><li><span style="color: #000;">List Value 1</span></li></ul>
                <p><span><strong>Header 2</strong></span></p>
                    <ul><li><span style="color: #000;">List Value 2</span></li></ul>
                <p><span><strong>Ignore</strong></span></p>
                    <ul><li><span style="color: #000;">List Value 3</span></li></ul>
                <p><span><strong>Header 3</strong></span></p>
                    <ul>
                        <li><span style="color: #000;">List Value A</span></li>
                        <li><span style="color: #000;">List Value B</span></li>
                        <li><span style="color: #000;">List Value C</span></li>
                    </ul>
                <p><span><strong>Ignore</strong></span></p>
                    <p>Text</p>
            </div>
        </div>
    </div>
    
    </body>
    </html>
    

    我正在尝试获取以下所有列表值 Header 3 ;但是,xpath在之后找不到匹配项 <p>

    这工作:

    //div[@class='this one']/p/span/strong[text() = 'Header 3']
    

    这不:

    //div[@class='this one']/p/span/strong[text() = 'Header 3']/following-sibling::ul[1]/li/span
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   kjhughes    7 年前

    问题是 strong 没有 ul 跟随兄弟姐妹。

    变化

    //div[@class='this one']/p/span/strong[text() = 'Header 3']/following-sibling::ul[1]/li/span
    

    //div[@class='this one']/p[span='Header 3']/following-sibling::ul[1]/li/span
    

    因为 p 确实有 UL 跟随兄弟姐妹。然后选择

    <span style="color: #000;">List Value A</span>
    <span style="color: #000;">List Value B</span>
    <span style="color: #000;">List Value C</span>
    

    按要求。

        2
  •  0
  •   melpomene    7 年前

    问题是,您的xpath表达式一直爬升到 <strong> 没有兄弟姐妹(它是它父母的独生子) <span> 元素)。具有以下内容的元素 <ul> 兄弟姐妹是 <p> 再向上。

    一般来说,您有两个选择:

    • 向下爬,然后后退:

      //div[@class='this one']/p/span/strong[text() = 'Header 3']/../../following-sibling::ul/li/span
      

      .. parent::node() .

    • 使用先行表达式:

      //div[@class='this one']/p[span/strong[text() = 'Header 3']]/following-sibling::ul/li/span
      

      任何东西 [ ] 是不移动文档树中当前位置的筛选条件。您可以在其中放置任意的xpath表达式。这里我们用它来寻找 p 包含一个 span 包含一个 strong 以及给定的文本。

    演示:

    function xpath(expr) {
      var found = document.evaluate(expr, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
      var results = [];
      for (var i = 0; i < found.snapshotLength; i++) {
        results.push(found.snapshotItem(i));
      }
      return results;
    }
    
    console.log(xpath("//div[@class='this one']/p/span/strong[text() = 'Header 3']/../../following-sibling::ul/li/span"));
    
    console.log(xpath("//div[@class='this one']/p[span/strong[text() = 'Header 3']]/following-sibling::ul/li/span"));
    <div>
        <div>
            <div>
            </div>
            <div class="this one">
                <p><span><strong>Ignore</strong></span></p>
                    <p>Text</p>
                <p><span><strong>Header 1</strong></span></p>
                    <ul><li><span style="color: #000;">List Value 1</span></li></ul>
                <p><span><strong>Header 2</strong></span></p>
                    <ul><li><span style="color: #000;">List Value 2</span></li></ul>
                <p><span><strong>Ignore</strong></span></p>
                    <ul><li><span style="color: #000;">List Value 3</span></li></ul>
                <p><span><strong>Header 3</strong></span></p>
                    <ul>
                        <li><span style="color: #000;">List Value A</span></li>
                        <li><span style="color: #000;">List Value B</span></li>
                        <li><span style="color: #000;">List Value C</span></li>
                    </ul>
                <p><span><strong>Ignore</strong></span></p>
                    <p>Text</p>
            </div>
        </div>
    </div>