Xpath 获取位于具有特定属性的两个元素之间的元素

Xpath get an element that lies between two elements with specific attributes

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

我希望 select 的元素如上所示。包含 space 的 w:r 元素前面必须紧跟 w:ins 或 w:del 元素,并且后面必须紧跟 w:ins 或 w:del 元素

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

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

但是,这似乎不起作用,因为它 select 包含 space 的所有 w:r 个元素。

我正在使用 Nokogiri。

有什么想法吗?

您可以尝试以下方法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

我终于找到了正确的解决方案,或者至少找到了一个可以给我想要的结果的解决方案:

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']]")