调用 super 的方法(向 Nokogiri XML 文档添加命名空间)

发布于 2024-12-12 20:34:30 字数 1089 浏览 1 评论 0原文

我有一个 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>

但是项目太多,我必须为每一项创建一个对象,序列化并保存在数据库中。因此,对于每个对象,我获取项目节点并将其转换为字符串并保存在对象中。

现在,在我从数据库恢复对象并且我想再次解析项目节点后,我遇到了这个名称空间问题。

I have an XML document which is missing some namespace declaration. I know I can define it when I use doc.xpath() method, like the following:

doc.xpath('//dc:title', 'dc' => 'http://purl.org/dc/elements/1.1/')

However I would like to add it once since I have a lot of xpath calls.

I found out that my Nokogiri::XML::Document is inherited from Nokogiri::XML::Node. And the Node class contains an add_namespace() method. However I can't call it, because it says it is undefined.

Is this because Ruby does not allow calling parent class's functions? Is there a way to go around this?

EDIT

I add the following console example:

> 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>

And here is the API document about Nokogiri::XML class

EDIT again:

The original doc was valid xml like this:

<root xmlns:ra="...">
  <item>
    <title/>
    <ra:price/>
  </item>
  <item>...
</root>

However there are too many items, and I have to create one object for each of these, serialize and save in the database. So for each object I took the item node and turn it into string and saved in the object.

Now after I revive the object from DB and I want to parse the item node again I came to this namespace issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷…雨湿花 2024-12-19 20:34:30
  1. 虽然 Nokogiri::XML::Document 确实继承自 Nokogiri::XML::Node,但某些方法在文档级别显式删除,包括 添加命名空间

    https://github.com/ enderlove/nokogiri/blob/master/lib/nokogiri/xml/document.rb#L203

  2. 正如 @pguardiario 所说,您想要添加命名空间添加到根元素,而不是文档。

  3. 但是,在解析文档之后再这样做就太晚了。 Nokogiri 已经创建了节点,丢弃了命名空间:

    需要“nokogiri”
    xml = ""
    doc = Nokogiri.XML(xml)
    p doc.at('b'). 命名空间
    #=>零
    
    doc.root.add_namespace 'a', 'foo'
    放置文档
    #=> 
    #=> 
    #=> >
    #=> 
    

在使用 Nokogiri 进行解析之前,您需要将源 XML 修复为字符串。 (除非 SAX 解析器有某种方法可以在您点击第一个节点时添加命名空间,然后再继续。)

  1. While Nokogiri::XML::Document does inherit from Nokogiri::XML::Node, some methods are explicitly removed at the document level, including add_namespace

    https://github.com/tenderlove/nokogiri/blob/master/lib/nokogiri/xml/document.rb#L203

  2. As @pguardiario notes, you want to add namespaces to the root element, not the document.

  3. However, doing this after parsing the document is too late. Nokogiri has already created the nodes, discarding the namespaces:

    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>
    

You'll need to fix your source XML as a string before parsing with Nokogiri. (Unless there's some way with the SAX parser to add the namespace when you hit the first node, before moving on.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文