我有一个XML文档缺少一些名称空间声明。我知道我可以在使用doc.xpath()
方法时定义它,如下所示:
doc.xpath('//dc:title', 'dc' => 'http://purl.org/dc/elements/1.1/')
但是我想添加它一次,因为我有很多xpath调用。
我发现我的Nokogiri::XML::Document
遗传自Nokogiri::XML::Node
。Node类包含一个add_namespace()
方法。但是我不能调用它,因为它说它是未定义的。
这是因为Ruby不允许调用父类的函数?有办法绕过这个吗?
编辑我添加以下控制台示例:
> c = Nokogiri.XML(doc_text)
> c.class
=> Nokogiri::XML::Document
> c.add_namespace('a','b')
NoMethodError: undefined method `add_namespace' for #<Nokogiri::XML::Document:0x007fea4ee22c60>
下面是Nokogiri::XML类的API文档
编辑:
原始文档是这样的有效xml:
<root xmlns:ra="...">
<item>
<title/>
<ra:price/>
</item>
<item>...
</root>
但是有太多的项目,我必须为每个项目创建一个对象,序列化并保存在数据库中。因此,对于每个对象,我将item节点转换为字符串并保存在对象中。
现在,在我从DB中恢复对象之后,我想再次解析项目节点,我遇到了这个名称空间问题。
-
虽然
Nokogiri::XML::Document
确实继承了Nokogiri::XML::Node
,但在文档级别明确删除了一些方法,包括add_namespace
https://github.com/tenderlove/nokogiri/blob/master/lib/nokogiri/xml/document.rb L203
-
正如@pguardiario所指出的,您希望将名称空间添加到根元素,而不是文档。
-
但是,在解析文档之后执行此操作已经太晚了。Nokogiri已经创建了节点,丢弃了名称空间:
require 'nokogiri' xml = "<r><a:b/></r>" doc = Nokogiri.XML(xml) p doc.at('b').namespace #=> nil doc.root.add_namespace 'a', 'foo' puts doc #=> <?xml version="1.0"?> #=> <r xmlns:a="foo"> #=> <b/> #=> </r>
在使用Nokogiri进行解析之前,需要将源XML固定为字符串。(除非SAX解析器可以在到达第一个节点时添加名称空间,然后再继续)