Ruby 如何通过使用XPath匹配文本来查找父节点

Ruby 如何通过使用XPath匹配文本来查找父节点,ruby,xml,xpath,nokogiri,Ruby,Xml,Xpath,Nokogiri,我有一些XML: <sys> <lang> <employee> <name>Employee 1</name> <code>4fdaa994-7015-4ec1-b365-de4ee0279966</code> </employee> <employee> <name>Employee 2</name>

我有一些XML:

<sys>
  <lang>
    <employee>
      <name>Employee 1</name>
      <code>4fdaa994-7015-4ec1-b365-de4ee0279966</code>
    </employee>
    <employee>
      <name>Employee 2</name>
      <code>1d960bdc-0853-49af-bb83-18cf92493897</code>
    </employee>
</lang>
</syz>
如何搜索和获取name=employee 1的employee节点

我试过了,但没用:

 obj.xpath("//sys/lang[/employee/name = 'Employee 1']")
这个XPath

/sys/lang/employee[name = 'Employee 1']
将选择名为employee 1的employee元素

为什么OP可能使用上述XPath获取无效表达式

转录错误

解决方案:使用复制和粘贴

单引号围绕单引号

解决方案:使用外部双引号:/sys/lang/employee[name='employee 1']

聪明的引语

解决方案:用单引号替换“和”

错误信息的错误解释

解决方法:仔细检查错误中提到的任何行号,或者尽可能地去除周围的代码,看看错误是否消失

如果上述任何一种可能性都不适用,请发布一个MCVE,包括提供的XPath和调用代码——在MCVE中生成无效表达式错误的完整代码,可能会有人立即发现问题。

此XPath

/sys/lang/employee[name = 'Employee 1']
将选择名为employee 1的employee元素

为什么OP可能使用上述XPath获取无效表达式

转录错误

解决方案:使用复制和粘贴

单引号围绕单引号

解决方案:使用外部双引号:/sys/lang/employee[name='employee 1']

聪明的引语

解决方案:用单引号替换“和”

错误信息的错误解释

解决方法:仔细检查错误中提到的任何行号,或者尽可能地去除周围的代码,看看错误是否消失


如果上述任何一种可能性都不适用,请发布一个MCVE,包括提供的XPath和调用代码——在MCVE中生成无效表达式错误的完整代码,有人可能会立即发现问题。

出于可读性原因,我非常喜欢使用CSS而不是XPath。Nokogiri实现了许多jQuery的扩展,使CSS更容易用于我们通常使用XPath的事情

我会这样做:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<sys>
  <lang>
    <employee>
      <name>Employee 1</name>
      <code>4fdaa994-7015-4ec1-b365-de4ee0279966</code>
    </employee>
    <employee>
      <name>Employee 2</name>
      <code>1d960bdc-0853-49af-bb83-18cf92493897</code>
    </employee>
</lang>
</syz>
EOT

emp1 = doc.at('employee name:contains("Employee 1")') # => #<Nokogiri::XML::Element:0x3ffed05285b4 name="name" children=[#<Nokogiri::XML::Text:0x3ffed05283d4 "Employee 1">]>
emp1.to_xml # => "<name>Employee 1</name>"
emp1.parent.to_xml # => "<employee>\n      <name>Employee 1</name>\n      <code>4fdaa994-7015-4ec1-b365-de4ee0279966</code>\n    </employee>"
还要注意的是,在选择器中为节点定义完整路径不是一种好的做法。如果HTML或XML更改了选择器将破坏的结构。相反,找到有用的地标,然后从一个地标跳到下一个地标。这样,选择器更有可能在标记中的更改中幸存下来。我只关心找到合适的。。。组合,而不是嵌入和下的两个标记

有时,获取所需信息的另一种方法是使用搜索并查看特定索引:

doc.search('employee').first.to_xml # => "<employee>\n      <name>Employee 1</name>\n      <code>4fdaa994-7015-4ec1-b365-de4ee0279966</code>\n    </employee>"
或:


at'some selector'相当于搜索'some selector'。首先。

出于可读性原因,我非常喜欢在XPath上使用CSS。Nokogiri实现了许多jQuery的扩展,使CSS更容易用于我们通常使用XPath的事情

我会这样做:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<sys>
  <lang>
    <employee>
      <name>Employee 1</name>
      <code>4fdaa994-7015-4ec1-b365-de4ee0279966</code>
    </employee>
    <employee>
      <name>Employee 2</name>
      <code>1d960bdc-0853-49af-bb83-18cf92493897</code>
    </employee>
</lang>
</syz>
EOT

emp1 = doc.at('employee name:contains("Employee 1")') # => #<Nokogiri::XML::Element:0x3ffed05285b4 name="name" children=[#<Nokogiri::XML::Text:0x3ffed05283d4 "Employee 1">]>
emp1.to_xml # => "<name>Employee 1</name>"
emp1.parent.to_xml # => "<employee>\n      <name>Employee 1</name>\n      <code>4fdaa994-7015-4ec1-b365-de4ee0279966</code>\n    </employee>"
还要注意的是,在选择器中为节点定义完整路径不是一种好的做法。如果HTML或XML更改了选择器将破坏的结构。相反,找到有用的地标,然后从一个地标跳到下一个地标。这样,选择器更有可能在标记中的更改中幸存下来。我只关心找到合适的。。。组合,而不是嵌入和下的两个标记

有时,获取所需信息的另一种方法是使用搜索并查看特定索引:

doc.search('employee').first.to_xml # => "<employee>\n      <name>Employee 1</name>\n      <code>4fdaa994-7015-4ec1-b365-de4ee0279966</code>\n    </employee>"
或:


“某个选择器”等同于搜索“某个选择器”。首先。

注意sys的结束标记是错误的。注意sys的结束标记是错误的。它给了我无效的表达式。然后,您在将其应用于代码时犯了一个错误,因为XPath肯定是有效和正确的。我已经尝试了很多次,但都不起作用,它给了我无效的表达式错误。是否与版本相关?编辑您的问题,并添加确切的代码和确切的错误消息。只要你一点点努力,我们就可以告诉你错误的确切位置。谢谢。你好@kjhughes,接受你的回答,谢谢你的帮助和描述性的回答。我相信它会帮助很多人给我提供无效的表达式。然后,你在将它应用到代码中时犯了一个错误,因为XPath绝对是有效和正确的。我已经尝试了很多次,但都不起作用,它给了我无效的表达式错误。是否与版本相关?编辑您的问题,并添加确切的代码和确切的错误消息。只要你一点点努力,我们就可以告诉你错误的确切位置。谢谢。你好@kjhughes,接受你的回答,谢谢你的帮助和描述性的回答。我相信这会帮助很多人