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