Получить значения из вложенного XML-файла с помощью Ruby / Nokogiri - PullRequest
0 голосов
/ 18 мая 2018

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

Мой текущий код:

require 'nokogiri'

doc = Nokogiri.XML(xml)

d=doc.xpath("//NtrkData/Rutins//GT_Nmbbrs/RngeDat")
puts d.xpath("//EE").text + "-" + d.xpath("//PR").text + "-" + d.xpath("//Brng").text + "-" + d.xpath("//Erng").text

Я получаю этот вывод

3Z94PL-45156-73359-86353

но что я хотел быполучить значение элемента EE, PR, Brng (если существует) и Erng (если существует).Все 4 значения в одной строке.

Таким образом, для следующего XML-файла искомый вывод будет:

3Z9 45 
4PL 156 73359 86353

XML-код:

xml =<<_
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<main>
<Oganin>
    <Oganna>EJ-MKKL</Oganna>
    <CutryI>YUFG</CutryI>
    <Ntwl>
    <Ntrk>
        <TGCo>KOLPWE</TGCo>
        <NtrkType>Uymmls</NtrkType>
        <NtrkData>
        <Rutins>
            <Rutinf>
            <CTT>
                <GT_Nmbbrs>
                <RngeDat>
                    <Nmbbr>
                    <EE>3Z9</EE>
                    <PR>45</PR>
                    </Nmbbr>
                </RngeDat>
                <RngeDat>
                    <Nmbbr>
                    <EE>4PL</EE>
                    <PR>156</PR>
                    <Srng>
                        <Brng>73359</Brng>
                        <Erng>86353</Erng>
                    </Srng>
                    </Nmbbr>
                </RngeDat>
                </GT_Nmbbrs>
            </CTT>              
            </Rutinf>
        </Rutins>
        </NtrkData>
    </Ntrk>
    </Ntwl>
</Oganin>
</main>
_

1 Ответ

0 голосов
/ 18 мая 2018

У Нокогири есть отличная документация, в которой четко указано, что Nokogiri::XML::NodeSet#inner_text не делает то, что вы ожидаете.Вместо этого он объединяет значения текстовых узлов .

Кроме того, нет способа просто набрать map(&:text), как предлагается в документации, поскольку вы, вероятно, хотите сохранить принадлежность <Srng>дочерние элементы, которые, очевидно, были бы невозможны при массовых запросах.

При этом вам необходимо запросить соответствующих родителей и выполнить итерации дочерних элементов:

d.xpath('//Nmbbr').
  map do |node|
    [
      node.xpath("./EE"),
      node.xpath("./PR"),
      node.xpath("./Srng").map do |node|
         %w[Brng Erng].map { |path| node.xpath("./#{path}") }
      end
    ]
  end.
  map { |nodes| nodes.flatten.map(&:text) }
  #⇒ [["3Z9", "45"], ["4PL", "156", "73359", "86353"]]

Теперь выполните итерацию результата и распечатайте его, как хотите.

...