【问题标题】:Xpath get an element that lies between two elements with specific attributesXpath 获取位于具有特定属性的两个元素之间的元素
【发布时间】:2018-05-12 14:23:12
【问题描述】:

示例 1

   <w:r>
        <w:t>gene</w:t>
   </w:r>
   <w:ins>
        <w:t>s</w:t>
   </w:ins>
   <w:r>
        <w:t> </w:t> #I want to select this element
   </w:r>
   <w:del >
        <w:t>house</w:t>
   </w:del>
   <w:r>
        <w:t>had</w:t>
   </w:r>
   <w:r>
        <w:t> </w:t>  #I do not want to select this element
   </w:r>
   <w:ins >
        <w:t>under</w:t>
   </w:ins>
   <w:del>
        <w:t>in</w:t>
    </w:del>
    <w:r>
        <w:t> </w:t>  #I want to select this element
    </w:r>
    <w:ins>
        <w:t>the</w:t>
    </w:ins>

示例 2

  <w:r>
    <w:t>specific genes</w:t>
  </w:r>
  <w:ins>
      <w:t>;</w:t>
  </w:ins>
  <w:del>
      <w:t>,</w:t>
  </w:del>
  <w:r>
    <w:t> </w:t>  #I don't want to select this one
  </w:r>
  <w:r>
    <w:t>SO</w:t>
  </w:r>

我希望选择的元素如上所示。包含空格的 w:r 元素必须直接在 w:ins 或 w:del 元素之前,并且还必须直接跟在 w:ins 或 w:del 元素之后

我从下面的表达式开始,但它没有考虑到前面的兄弟可能是一个 w:del 元素。对于以下兄弟姐妹也是如此。它还必须检查元素之前或之后的元素,看看它是 w:ins 还是 w:del 元素。

search("//w:r[. = ' ' and previous-sibling::w:ins and following-sibling::w:del]")

但是,这似乎不起作用,因为它选择了所有包含空格的 w:r 元素。

我正在使用 Nokogiri。

有什么想法吗?

【问题讨论】:

    标签: xml xpath nokogiri xpath-2.0


    【解决方案1】:

    你可以试试下面的xpath

    //*[local-name()='r' and node()='' and preceding-sibling::*[local-name()='ins'] and following-sibling::*[local-name()='ins'] ]
    

    输入:

    more example1.xml 
    <?xml version="1.0"?>
    <root xmlns:w="http://so.com">
      <w:r>
        <w:t xml:space="preserve">gene</w:t>
      </w:r>
      <w:ins>
        <w:r>
          <w:t>s</w:t>
        </w:r>
      </w:ins>
      <w:del>
        <w:r>
          <w:delText>,</w:delText>
        </w:r>
      </w:del>
      <w:r><w:t xml:space="preserve"/>  #I want to select this element
          </w:r>
      <w:ins>
        <w:r>
          <w:t>under</w:t>
        </w:r>
      </w:ins>
      <w:del>
        <w:r>
          <w:delText>in</w:delText>
        </w:r>
      </w:del>
      <w:r>
        <w:t xml:space="preserve">both</w:t>
      </w:r>
      <w:del>
        <w:r>
          <w:delText xml:space="preserve">the</w:delText>
        </w:r>
      </w:del>
    </root>
    

    第二个文件:

    more example2.xml
    <?xml version="1.0"?>
    <root xmlns:w="http://so.com">
      <w:r>
        <w:t xml:space="preserve">phenotypic specific genes</w:t>
      </w:r>
      <w:ins>
        <w:r>
          <w:t>;</w:t>
        </w:r>
      </w:ins>
      <w:del>
        <w:r w:rsidDel="00167AE4" w:rsidRPr="006C5D4F">
          <w:delText>,</w:delText>
        </w:r>
      </w:del>
      <w:r><w:t xml:space="preserve"/> #I don't want to select this one
      </w:r>
      <w:r w:rsidRPr="006C5D4F">
        <w:t>SOX9</w:t>
      </w:r>
    </root>
    

    结果:

    example1.xml

    $xmllint --xpath "//*[local-name()='r' and node()='' and preceding-sibling::*[local-name()='ins'] and following-sibling::*[local-name()='ins'] ]" example1.xml
    <w:r>
        <w:t xml:space="preserve"/>  #I want to select this element
    </w:r>
    

    example2.xml

    $ xmllint --xpath "//*[local-name()='r' and node()='' and preceding-sibling::*[local-name()='ins'] and following-sibling::*[local-name()='ins'] ]" example2.xml 
    XPath set is empty
    

    【讨论】:

    • Allan 我在我的完整文件上尝试了你的代码,它匹配了 52 个段,而它应该只匹配一个。
    • 实际上,当我尝试它时,这让我很接近,但是当我应该只得到一个时,我得到了两个片段。其中一个片段后面不是 w:ins 或 w:del,而是我不想要的 w:r 元素。
    【解决方案2】:

    我终于能够找到正确的解决方案,或者至少找到一个可以为我提供所需结果的解决方案:

    search("//w:r[. = ' ' and following-sibling::*[position()=1][name()='w:del' or name()='w:ins']and preceding-sibling::*[position()=1][name()='w:del' or name()='w:ins']]")
    

    【讨论】:

      猜你喜欢
      • 2012-06-07
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 2023-01-19
      • 2012-11-30
      • 1970-01-01
      • 2012-01-01
      • 2011-05-06
      相关资源
      最近更新 更多