Как объединить два тега XML с помощью Ruby / Nokogiri? - PullRequest
0 голосов
/ 10 февраля 2012

Я использую Ruby для получения XML-документа в следующем формате:

<project>
  <users>
   <person>
     <name>LUIS</name>
   </person>
   <person>
     <name>JOHN</name>
   </person>
  </users>
</project>

Я хочу знать, как получить следующий результат с объединенными тегами:

<project>
    <users>
      <person>
        <name>LUIS JOHN</name>
      </person>
    </users>
</project>

Вот код, который я использую:

file = File.new( "proyectos.xml" )
doc3 = Nokogiri::XML(file)
a=0

@participa = doc3.search("person")
@participa.each do |i|

     @par = @participa.search("name").map { |node| node.children.text }

     @par.each do |i|
         puts @par[a]
         puts '--'
         a = a + 1
    end 

end

1 Ответ

1 голос
/ 11 февраля 2012

Вместо того, чтобы поставлять код, вот как ловить рыбу:

Чтобы разобрать ваш XML в Nokogiri, который я настоятельно рекомендую:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<project>
  <users>
   <person>
     <name>LUIS</name>
   </person>
   <person>
     <name>JOHN</name>
   </person>
  </users>
</project>
EOT

Это дает вам doc переменную, которая является DOM как Nokogiri :: XML :: Document. Из этого вы можете искать, либо для соответствия узлов или конкретного узла. search позволяет передавать XPath или CSS-аксессор, чтобы найти то, что вы ищете. Я рекомендую CSS для большинства вещей, потому что он более читабелен, но в XPath есть несколько отличных инструментов, позволяющих разобраться в структуре вашего XML, поэтому я часто получаю и то и другое в своем коде.

Итак, doc.at('users') - это аксессор CSS для поиска первого users узла. doc.search('person') вернет все узлы, соответствующие тегу person, как NodeSet, который в основном является массивом, который вы можете перечислить или перебрать.

В Nokogiri есть метод text для узла, который позволяет получить текстовое содержимое этого узла, включая все возвраты каретки между узлами, которые обычно считаются форматированием в XML при его передаче по документу. Когда у вас есть текст узла, вы можете применить обычные команды обработки строк Ruby, такие как strip, squish, chomp и т. Д., Чтобы преобразовать текст в более удобный формат.

В Nokogiri также есть метод children=, который позволяет вам переопределить дочерние узлы узла. Вы можете передать созданный вами узел, NodeSet или даже текст, который вы хотите визуализировать, в XML на этом этапе.

В быстром эксперименте у меня есть код, который делает то, что вы хотите, в основном из четырех строк. Но я хочу увидеть вашу работу, прежде чем поделиться тем, что я написал.

Наконец, puts doc.to_xml позволит вам легко увидеть, были ли ваши изменения в документе успешными.


Вот как бы я это сделал:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<project>
  <users>
   <person>
     <name>LUIS</name>
   </person>
   <person>
     <name>JOHN</name>
   </person>
  </users>
</project>
EOT

XML теперь анализируется в DOM. Найдите теги users, найдите встроенные теги name и извлеките из них текст. Объедините результаты в одну строку, разделенную пробелом. Затем замените дочерние элементы тега users на желаемые результаты:

doc.search('users').each do |users|
  user_names = users.search('name').map(&:text).join(' ')
  users.children = "<person><name>#{ user_names }</name></person>"
end

Если вы выведете получившийся XML, вы получите:

puts doc.to_xml

<?xml version="1.0"?>
<project>
  <users><person><name>LUIS JOHN</name></person></users>
</project>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...