Ruby REXML: получить значение элемента XML - PullRequest
1 голос
/ 18 ноября 2011

Я пытаюсь поместить значения некоторых элементов xml в массив, используя rexml. Вот пример того, что я делаю:

doc = Document.new("<data><title>This is one title</title><title>This is another title</title></data>")
XPath.each( doc, "*/title") { |element| 
    puts element.text
}

Однако, это выводит:

[<title> ... </>, <title> ... </>] 

Как я могу получить его для вывода массива, содержащего "Это один заголовок" и "Это другой заголовок"?

Ответы [ 2 ]

4 голосов
/ 18 ноября 2011

Перемещение моего комментария к ответу, по запросу:

Хотя puts может преобразовать свой аргумент в любом случае в строку, XPath может вернуть текстовый узел в первую очередь:

XPath.each(doc, "*/title/text()") {...
3 голосов
/ 18 ноября 2011

Ты уверен в этом? Вот полная программа:

#!/usr/bin/ruby

require 'rexml/document'
include REXML

doc = Document.new("<data><title>This is one title</title><title>This is another title</title></data>")
XPath.each( doc, "*/title") { |element|
    puts element.text
}

Выход:

This is one title
This is another title

Редактировать: Звучит так, будто ОП продолжился, но я думаю, что здесь должны быть некоторые пояснения для будущих посетителей. Я одобрил хороший ответ @ LarsH, но следует отметить, что, учитывая конкретный ввод ОП, element.text должен выдавать точно такой же вывод , как в результате выбора узлов text() в первую очередь. С Документы :

текст (путь = ноль) Удобный метод, который возвращает значение String первого дочернего текстового элемента, если таковой существует, и ноль в противном случае.

Пример ввода, приведенный в исходном вопросе, показывает <title> элементов, содержащих только один текстовый узел в каждом случае. Следовательно, эти два метода одинаковы (в данном случае).

Однако обратите внимание на это важное примечание:

Обратите внимание, что элемент может иметь несколько элементов Text, возможно разделенные другими детьми. Имейте в виду, что этот метод только возвращает первый текстовый узел.

Вы можете получить всех дочерних текстовых узлов элемента, используя texts() (множественное число).

Я подозреваю, что многие люди действительно ищут, это эквивалент textContent DOM (или его незаконнорожденного двоюродного брата innerText). Вот как вы можете сделать это в Ruby:

XPath.each(doc, "*/title") { |el|
    puts XPath.match(el,'.//text()').join
}

Это объединяет весь текст потомков каждого элемента в одну строку.

Короткий ответ: короткого ответа нет. Какой из них вы хотите, если таковой имеется, сильно зависит от контекста. Единственное требование в исходном вопросе - "поместить значения некоторых элементов xml в массив" , что на самом деле не является большой спецификацией.

...