我有一个像这样的xml文件:https://gist.github.com/1966260。
我想转储架构元素(xs:element)。
我试试:
doc.xpath("//xs:element")
doc.xpath("//element")
doc.xpath("element")
不工作......
任何建议?
感谢
答案 0 :(得分:2)
@BenTaitelbaum这是预期的行为。 http://nokogiri.org/Nokogiri/XML/Node.html#method-i-xpath。
不同的文档可以为相同的命名空间提供不同的前缀。例如,本文档使用“xs”作为“http://www.w3.org/2001/XMLSchema”的名称空间前缀。但是其他一些文档可能会使用“xmls”。通过提供命名空间映射,xpath
方法将始终找到“http://www.w3.org/2001/XMLSchema”命名空间中的节点,即使前缀不同也是如此。他们之所以这样做是因为URL是普遍唯一的,但前缀不是也可能会发生冲突,并且在每个节点上使用URL都会很乏味和令人厌恶,而不是XML曾经遇到过这种问题(zing)。
好读:http://tenderlovemaking.com/2009/04/23/namespaces-in-xml/
你的方式是正确/良好/健康。但是,本着完整的精神,这里有一些其他选择是阴暗的,可能会伤害你:
如果您想通过命名空间前缀而不是URL(这可能是一个坏主意)进行查询,您可以事先collect all the namespaces。 (这仅适用于文档中的URL与前缀一对一映射。如果不是,则可能会失败)
doc = Nokogiri::XML(open(the_url))
namespaces = doc.collect_namespaces
doc.xpath('//xs:schema', namespaces)
如果你想完全忽略命名空间(这可能是一个坏主意),你可以remove them entirely。
doc = Nokogiri::XML(open(the_url))
doc.remove_namespaces!
doc.xpath('//schema')
答案 1 :(得分:1)
这有效:
require 'nokogiri'
require 'open-uri'
doc = Nokogiri::XML(open('https://raw.github.com/gist/1966260/8769a795b2ba83ceea6aaa45365b01cf344087b0/gistfile1.xml'))
doc.xpath('//xs:schema', 'xs' => 'http://www.w3.org/2001/XMLSchema')
我不确定这是否是nokogiri或预期行为的错误,但是值得在邮件列表上讨论或为其创建问题。