Вызов метода super (добавить пространство имен в XML-документ Nokogiri)

У меня есть 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>

А вот документ API о Nokogiri:: класс XML

РЕДАКТИРОВАТЬ снова:

Исходный документ был действительным xml следующим образом:

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

Однако предметов слишком много, и мне нужно создать один объект для каждого из них, сериализовать и сохранить в базе данных. Поэтому для каждого объекта я взял узел item, превратил его в строку и сохранил в объекте.

Теперь, после того, как я восстановил объект из БД и хочу снова проанализировать узел элемента, я пришел к этой проблеме с пространством имен.

1 ответ

Решение
  1. В то время как Nokogiri::XML::Document наследуется от Nokogiri::XML::Nodeнекоторые методы явно удалены на уровне документа, в том числе add_namespace

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

  2. Как отмечает @pguardiario, вы хотите добавить пространства имен к корневому элементу, а не к документу.

  3. Однако делать это после разбора документа уже поздно. 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>
    

Вам нужно исправить исходный XML-код в виде строки перед синтаксическим анализом с Nokogiri. (Если только с парсером SAX не существует способа добавить пространство имен при нажатии на первый узел, прежде чем двигаться дальше.)

Другие вопросы по тегам