Как мне разобрать XML и выполнить действия в зависимости от содержимого узла? - PullRequest
0 голосов
/ 03 декабря 2011

У меня есть XML-файл, который будет выводить строку:

<mystring>
    <manipulate type="caps">
        <string>Hello There!</string>
        <repeat times="4">
            <string> FooBar</string>
        </repeat>
    </manipulate>
    <string>!</string>
</mystring>

Строка, которую я хочу создать:

HELLO THERE! FOOBAR FOOBAR FOOBAR FOOBAR!

Я хотел бы интерпретировать узлы XML ивыполнять определенные действия или выводить определенные строки.Я хотел бы чистый способ сделать это.Это просто упрощенная версия, и будут другие узлы с более сложными функциями, но мне нужна помощь, чтобы начать работу.

Я попытался сделать это с помощью Nokogiri, но немного борюсь.

Ответы [ 2 ]

0 голосов
/ 03 декабря 2011

Моя попытка, которая использует рекурсию и карту (я считаю функциональное программирование элегантным:)

требуется 'nokogiri'

def build_string_from_xml(nodes)
  nodes.map { |node|
    inner_str = build_string_from_xml(node.xpath("./*"))
    case node.name
    when "string"
      node.content
    when "repeat"
      if node[:type] == "numbered"
        1.upto(node[:times].to_i).map { |i|
          inner_str + i.to_s
        }.join
      else
        inner_str * node[:times].to_i
      end
    when "manipulate"
      if node[:type] == "caps"
        inner_str.upcase
      else
        raise ArgumentError, "Don't know that manipulation type: %s" % node[:type]
      end
    else
      raise ArgumentError, "Don't know that tag: %s" % node.name
    end
  }.join
end

doc = Nokogiri::XML.parse(<<-XML)
<mystring>
  <manipulate type="caps">
    <string>Hello There!</string>
    <repeat times="4">
      <string> FooBar</string>
    </repeat>
    <string>!</string>
  </manipulate>

  <repeat times="3" type="numbered">
    <string> FooBar</string>
  </repeat>
</mystring>
XML

p build_string_from_xml(doc.xpath("//mystring/*"))
0 голосов
/ 03 декабря 2011
f = File.open("file.xml")
doc = Nokogiri::XML(f)
f.close

result = []

doc.root.children.each do |node|
  if node.name == "string"
    result.push(node.inner_text)
    repeat = node.children[0]
    times = repeat["times"]
    for i in 1..times do
      result.append(repeat.inner_text)
    end
  end
  ...
end

" ".join(result)

Что-то в этом роде. Если честно, я сам не использовал Nokogiri, но, надеюсь, это было полезно.

...