Вызов метода super (добавить пространство имен в XML-документ Nokogiri) - PullRequest
3 голосов
/ 01 ноября 2011

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

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

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

1 Ответ

4 голосов
/ 02 ноября 2011
  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>
    

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

...