2010-08-25 2 views
41

Я разборе XML-документ, который выглядит примерно так:Использование XPath на одном узле возвращает элементы во всех узлах

<MyBook> 
    <title>Favorite Poems</title> 
    <issn>123-456</issn> 
    <pages>45</pages> 
</MyBook> 
<MyBook> 
    <title>Chocolate Desserts</title> 
    <issn>654-098</issn> 
    <pages>100</pages> 
</MyBook> 
<MyBook> 
    <title>Jabberwocky</title> 
    <issn>454-545</issn> 
    <pages>19</pages> 
</MyBook> 

Я использую XPath, чтобы вытащить MyBook узлы и перебирать их, как так:

xmldoc.xpath("//MyBook").each do |node| 
    mytitle=node.xpath("//title").text 
    puts mytitle 
end 

выход выглядит следующим образом:

Favorite PoemsChocolateDessertsJabberwocky 
Favorite PoemsChocolateDessertsJabberwocky 
Favorite PoemsChocolateDessertsJabberwocky 

, как если бы узел действительно весь xmldoc. Однако, если я распечатаю узел внутри итератора, каждый раз, когда это то, что я ожидаю, просто один узел MyBook. Мне нужно иметь возможность вытягивать дочерние узлы из каждого узла последовательно, а не весь один и тот же дочерний узел из всего документа. Что я делаю не так?

ответ

67

При использовании //title это поиск всех <title> элементов, начинающихся с корня документа. Используйте либо title, чтобы найти дочерние титры, либо .//title, если вы хотите найти названия, даже если они вложены внутри других элементов.

+0

aha! Большое спасибо. Поэтому не имеет значения, что я применяю выражение xpath к узлу? – Sabrina

+2

Помещение '/' или '//' спереди делает XPath абсолютным путем. Когда вы используете те, оценщик XPath игнорирует узел контекста и начинается с корня документа. –

+0

@JohnKugelman http://stackoverflow.com/questions/36412067/use-nokogiri-xpath-to-select-root-and-children-matching-expression – karl