首页 文章

我该如何制定这个xpath表达式?

提问于
浏览
3

给出以下div元素

<div class="info">
    <a href="/s/xyz.html" class="title">title</a>
    <span class="a">123</span>
    <span class="b">456</span>
    <span class="c">789</span>
</div>

我想用类“b”检索span的内容 . 但是,我想要解析的一些div缺少第二个 Span (类“b”和“c”) . 对于这些div,我希望span的内容与类“a” . 是否可以创建一个选择此的XPath表达式?

如果不可能,是否可以创建一个检索div的全部内容的选择器?即检索

<a href="/s/xyz.html" class="title">title</a>
<span class="a">123</span>
<span class="b">456</span>
<span class="c">789</span>

如果我能做到这一点,我可以使用正则表达式来查找我想要的数据 . (我可以选择div中的文本,但我不知道如何选择标签 . 只是文本产生123456789.)

3 回答

  • 1

    xpath表达式应该类似于:

    //div/span[@class='b'] | //div[not(./span[@class='b'])]/span[@class='a']
    

    union运算符 | 左边的表达式将选择所有div中的所有b-class spans,右边的表达式将首先查询没有b-class span的所有div,然后选择他们的a-class span . |运算符结合了两组的结果 .

    有关选择带有not()的节点和here用于将结果与|进行组合,请参阅here运营商 .

    另外,要参考问题的第二部分,请查看here . 在xpath中使用node()可以选择所选节点下方的所有内容(节点文本) . 所以你可以获得返回的div中的所有内容

    //div/node()
    

    用于将来通过其他方式处理 .

  • 2

    More efficient -- requires no union

    //div/span
              [@class='b'
               or
                 @class='a'
                and
                 not(parent::*[span[@class='b']])
               ]
    

    一个表达式(如下所示)是两个绝对“ // 表达式”的并集,通常执行两个完整的文档树遍历,然后联合操作按文档顺序执行重复数据删除和排序 - 所有这些都可能显着低于单树遍历,除非XPath处理器具有智能优化器 .

    An example of such inefficient expression

    //div/span[@class='b'] | //div[not(./span[@class='b'])]/span[@class='a']
    

    XSLT - based verification

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="/">
      <xsl:copy-of select=
      "//div/span
              [@class='b'
               or
                 @class='a'
                and
                 not(parent::*[span[@class='b']])
               ]"/>
     </xsl:template>
    </xsl:stylesheet>
    

    When this transformation is applied on the provided XML document

    <div class="info">
        <a href="/s/xyz.html" class="title">title</a>
        <span class="a">123</span>
        <span class="b">456</span>
        <span class="c">789</span>
    </div>
    

    The Xpath expression is evaluated and the selected elements (in this case just one) are copied to the output

    <span class="b">456</span>
    

    When the same transformation is applied on a different XML document, where there is no class='b':

    <div class="info">
        <a href="/s/xyz.html" class="title">title</a>
        <span class="a">123</span>
        <span class="x">456</span>
        <span class="c">789</span>
    </div>
    

    the same XPath expression is evaluated and the correctly selected element is copied to the output

    <span class="a">123</span>
    
  • 0

    在没有union运算符的情况下对输入起作用的表达式:

    //div/span[@class='a' or @class='b'][count(../span[@class='b']) + 1]
    

    这只是为了好玩 . 我可能会在 生产环境 代码中使用更像@ inVader的答案 .

相关问题