Вызов метода 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>

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

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


person lulalala    schedule 01.11.2011    source источник
comment
может быть, вы хотите c.root.add_namespace('a','b')   -  person pguardiario    schedule 01.11.2011
comment
Итак, чтобы было ясно, у вас есть недопустимый XML-документ, такой как <root><foo:bar /></root>, и вы хотите определить пространство имен foo до или как часть синтаксического анализа? Не могли бы вы предоставить простой пример, подобный приведенному выше, и указать, чего вы хотите достичь?   -  person Phrogz    schedule 02.11.2011
comment
Ага, спасибо за ответ. я отредактировал свой вопрос   -  person lulalala    schedule 02.11.2011


Ответы (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 каким-то образом не добавляет пространство имен при переходе к первому узлу, прежде чем двигаться дальше.)

person Phrogz    schedule 01.11.2011