Nokogiri/Xpath名称空间查询

Jam*_*mie 35 ruby xml xpath nokogiri

我正在尝试dc:title使用xpath 拉出元素.我可以使用以下代码提取元数据.

doc = <<END
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="2.0">
  <metadata xmlns:dc="URI">
    <dc:title>title text</dc:title>
  </metadata>
</package>
END

doc = Nokogiri::XML(doc)

# Awesome this works!
puts '//xmlns:metadata'
puts doc.xpath('//xmlns:metadata')
# => <metadata xmlns:dc="URI"><dc:title>title text</dc:title></metadata>
Run Code Online (Sandbox Code Playgroud)

如您所见,上面似乎正常工作.但是,我似乎无法从此节点树获取标题信息,以下所有内容都失败了.

puts doc.xpath('//xmlns:metadata/title')
# => nil

puts doc.xpath('//xmlns:metadata/dc:title')
# => ERROR: `evaluate': Undefined namespace prefix

puts doc.xpath('//xmlns:dc:title')
# => ERROR: 'evaluate': Invalid expression: //xmlns:dc:title
Run Code Online (Sandbox Code Playgroud)

有人可以解释如何使用上面的xml doc在xpath中使用命名空间.

Mar*_*mas 67

解析时需要注册所有名称空间.Nokogiri自动在根节点上注册名称空间.任何不在根节点上的命名空间,您必须自己注册.这应该工作:

puts doc.xpath('//dc:title', 'dc' => "URI")
Run Code Online (Sandbox Code Playgroud)

或者,您可以完全删除命名空间.只有在您确定没有冲突的节点名称时才执行此操作.

doc.remove_namespaces!
puts doc.xpath('//title')
Run Code Online (Sandbox Code Playgroud)

  • 使用`remove_namespace!`是最先尝试的事情.但请注意:如果您正在修改此XML并将其提交到外部API,则API(通常)会在没有命名空间的情况下拒绝它. (2认同)