Как выбрать поддерево XML на основе его содержимого? - PullRequest
3 голосов
/ 01 декабря 2011

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

Пример:

<records>   
    <name>Rose</name>
    <date>12-1-11</date>
</records>
<records>   
    <name>jon</name>
    <date>12-1-11</date>
</records>
<records>   
    <name>Tom</name>
    <date>12-1-11</date>
</records>

Я хочунайдите "Rose" и получите весь элемент <records> и его дочерние элементы.


Спасибо всем, вы очень быстрые.

У меня есть еще вопрос, если у меня есть еще несколько узлови они не являются записями, как мне искать во всех них?

<records>   
    <name>Rose</name>
    <date>12-1-11</date>
</records>
<cars>   
    <name>jon</name>
    <date>12-1-11</date>
</cars>
<houses>   
    <name>Tom</name>
    <date>12-1-11</date>
</houses>

На этот раз я буду искать по дате = 11-1-11.

Ответы [ 3 ]

4 голосов
/ 01 декабря 2011

Вы выбираете не по атрибуту, а по элементу.Это разницаВ любом случае, вот выражение XPath, которое вы можете использовать:

//records[name[text()='Rose']]

Можно также сделать короче:

//records[name='Rose']

Или, если вы опасаетесь, что пустое пространство испортит вещи:

//records[name[normalize-space(text()) = 'Rose']]
2 голосов
/ 01 декабря 2011

Ответ на основе XPath @ G_H - это то, что я лично использовал бы.Однако, для полноты, вот как вы можете сделать это в Nokogiri, используя только синтаксис CSS-селектора и немного больше Ruby:

names = doc.css('name')
rose  = names.find{ |el| el.text == "Rose" }
rose_record = rose.parent

Или в одной строке:

rec = doc.css('name').find{ |el| el.text=="Rose" }.parent

Для получения дополнительной информации см. Документацию Enumerable#find.

Редактировать : поскольку вы новичок в Nokogiri, вот как вы создаете документ дляначать запросы:

require 'nokogiri' # gem install nokogiri 
doc = Nokogiri.XML(File.read('my.xml'))
0 голосов
/ 01 декабря 2011

Я не знаю Ruby или Nokogiri, но проверил следующее xpath выражение в xqilla и, похоже, работает.

//records[data(name) = "Rose"]

Выход:

<records>   
    <name>Rose</name>
    <date>12-1-11</date>
</records>
...