REXML无法从属性中进行选择。错误或不正确的XPath?

时间:2011-02-04 12:47:48

标签: ruby xpath rexml

我尝试通过特殊属性从SVG文档中选择一个元素。 我设置了一个简单的例子。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg">
  <g id='1'>
    <path id='2' type='A'/>
    <rect id='3' type='B'/>
  </g>
</svg>

现在我使用以下语法通过其属性检索路径元素&#34;输入&#34;:

require 'rexml/document'
include REXML
xmlfile = File.new "xml_as_specified_above.svg"
xmldoc = Document.new(xmlfile)
XPath.match( xmldoc.root, "//path[@type]" )

直接来自http://www.w3schools.com/xpath/xpath_syntax.asp的语法。 我希望这个表达式选择路径元素,但接下来是:

>> XPath.match( xmldoc.root, "//path[@type]" )
=> []

那么,XPath中通过它的属性解决路径元素的正确语法是什么? 或者REXML中是否存在错误(使用3.1.7.3)? 还有点用于检索&#34; rect&#34;元件。

4 个答案:

答案 0 :(得分:3)

看起来正在拾取旧版本的rexml,它不支持完整的XPath规范。

尝试检查puts XPath::VERSION的输出以确保显示3.1.73。

答案 1 :(得分:0)

您需要考虑默认命名空间。使用XPath 1.0,您需要将前缀(例如svg)绑定到名称空间URI http://www.w3.org/2000/svg,然后使用类似//svg:path[@type]的路径。如何将前缀绑定到用于XPath评估的URI取决于您使用的XPath API,如果您在API文档中找不到方法或属性,恐怕我不知道如何使用您的Ruby API。然后你可能会有其他人来告诉我们。

答案 2 :(得分:0)

这些天我们很多人使用Nokogiri而不是另一个早期的Ruby XML解析器ReXML或Hpricot。

Nokogiri支持XPath和CSS访问器,因此您可以使用熟悉的HTML类型路径来获取节点:

require 'nokogiri'

svg = %q{<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg">
  <g id='1'>
    <path id='2' type='A'/>
    <rect id='3' type='B'/>
  </g>
</svg>
}

doc = Nokogiri::XML(svg)
puts doc.search('//svg:path[@type]')
puts doc.search('svg|path[@type]')
puts doc.search('path[@type]')

puts doc.search('//svg:rect')
puts doc.search('//svg:rect[@type]')
puts doc.search('//svg:rect[@rect="B"]')
puts doc.search('svg|rect')
puts doc.search('rect')

# >> <path id="2" type="A"/>
# >> <path id="2" type="A"/>
# >> <path id="2" type="A"/>

# >> <rect id="3" type="B"/>
# >> <rect id="3" type="B"/>
# >> <rect id="3" type="B"/>
# >> <rect id="3" type="B"/>

第一个路径是带有命名空间的XPath。第二个是带有命名空间的CSS。第三个是没有命名空间的CSS。对人类友好的Nokogiri将允许我们deal and dispense with the namespaces两种方式,假设我们知道为什么命名空间是好的。

答案 3 :(得分:0)

这是最常见的问题:默认命名空间问题。

解决方案:

而不是:

//path[@type]

使用

//svg:path[@type]