2015-12-05 3 views
2

Я пытаюсь выбрать два узла вместе в документе XML и распечатать их. Я не могу заставить их печатать вместе. Они всегда выводятся как «список первых узлов», а затем «список вторых узлов». Примером может иллюстрировать лучше:Выбор узла с помощью Nokogiri, а затем следующего указанного узла

<result> 
    <name>Peter</name> 
    <school>main school</school> 
    ... 
    <score>4.5</score> 
</result> 
<result> 
    <name>John</name> 
    .. 
    ... 
    <score>3.5</score> 
</result> 

Форматы каждого <result> не всегда одинаковы. Мне нужно, чтобы выбрать <name> и <score> таким образом они появляются вместе:

Peter 
4.5 
John 
3.5 

или

Peter 4.5 
John 3.5 

Я могу только получить результаты до сих пор, как это:

Peter 
John 
4.5 
3.5 

Я пытался различные различные методы, такие как:

doc.xpath("//name/").xpath("//score").each do |link| 
    puts link 

и другие комбинации вложенных do/end петель, но ничего не работает. Любые идеи?

+0

Ваш XML недопустим. Важно предоставить полезный контент, который мы можем использовать с кодом, который вы поставляете. Ваш код ничего не делает, поскольку он не является синтаксически правильным. Пожалуйста, прочитайте «[ask]». –

ответ

3

Ярчайший путь, вероятно, сначала выберите result узлов, то для каждого result выбрать его name и score узлов:

doc.xpath('//result').each do |result| 
    name = result.at_xpath('./name').text 
    score = result.at_xpath('./score').text 
    # handle name and score however you want... 
end 

(Это предполагает, каждый result имеет один name ребенка и одного score ребенка.)

+0

Спасибо. Это краткий ответ на эту проблему. Я не понимал, что могу отформатировать такие варианты, как «./name» и т. Д. Прекрасно работает. – boogiewonder

3

Возможно, вы можете хранить значения name в массиве, а затем перебирать массив по мере того, как вы перебираете значения score, печатая их как в то же время:

array_of_names = [] 

doc.xpath("//name").each do |name| 
    array_of_names << name 
end 

counter = 0 
doc.xpath("//score").each do |score| 
    puts "#{array_of_names[counter]}: #{score}" 
    counter += 1 
end 
+0

Спасибо @ GDP2. Я выбрал другой ответ ниже, поскольку он более компактный, но я вижу, что ваше решение также будет работать. Я ценю работу. – boogiewonder

+0

@boogiewonder Np, я также согласен с тем, что другой ответ действительно. Как говорится, есть несколько способов сделать это. Спасибо за upvote, кстати. – GDP2

Смежные вопросы