2009-11-20 2 views
0

У меня есть простая строка XML, которая более или менее всегда одинакова. Я бы предпочел не использовать синтаксический анализатор XML для такого небольшого фрагмента кода, и я бы мог помочь Regexp.Ruby Regexp для извлечения определенных элементов в XML-строке

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

<?xml version="1.0"?> 
<methodCall> 
    <methodName>weblogUpdates.extendedPing</methodName> 
    <params> 
    <param> 
     <value>Official Google Blog</value> 
    </param> 
    <param> 
     <value>http://googleblog.blogspot.com/</value> 
    </param> 
    <param> 
     <value>http://googleblog.blogspot.com/</value> 
    </param> 
    <param> 
     <value>http://googleblog.blogspot.com/atom.xml</value> 
    </param> 
    </params> 
</methodCall> 

Я хочу, чтобы извлечь значения каждых пары (и поддержание порядка).

я придумал /<value>(.*)<\/value>/xi, но это просто macthes самое первое значение:/

ответ

3

Parsing XML with Ruby is trivial, пожалуйста, не пытайтесь разобрать XML с помощью регулярного выражения - это, как известно, трудно и подвержен ошибкам.

Хотя может возникнуть соблазн попробовать и использовать регулярное выражение, пожалуйста, не делайте этого. Независимо от того, насколько сильно вы пытаетесь разбить этот гвоздь отверткой, он не будет работать как молоток - пожалуйста, используйте один из многих замечательных молотков в вашем распоряжении.

+1

Пожалуйста, прекратите распространение этого мема: разбор XML с регулярным выражением не является «печально трудным и подверженным ошибкам», это просто невозможно. И не невозможно в смысле «невозможно получить право», но доказуемо математически невозможно.На самом деле, почти каждый студент CS на всей планете в свое время в течение своей карьеры доказал эту невозможность в каком-то задании на домашнюю работу или другом. –

+2

@ Йорг - Боюсь, что мы с тобой говорим о двух совершенно разных вещах. Математическая невозможность сильно отличается от реальной невозможности (из-за отсутствия лучшей фразы). Невозможно использовать регулярные выражения для XML? Нет, конечно, нет - вполне возможно использовать регулярные выражения для взлома решения, которое будет работать большую часть времени. Я понимаю вашу точку зрения (и соглашаюсь с вами в принципе), но она действительно не имеет большого значения для практического обсуждения, подобного этому. –

1

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

Если вы похожи на меня, я бы сделал это так:

x = File.new("test.xml", "r").read 
puts x.scan(/<value>(.*)<\/value>/) 

Какие результаты в:

Official Google Blog 
http://googleblog.blogspot.com/ 
http://googleblog.blogspot.com/ 
http://googleblog.blogspot.com/atom.xml 

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

x.scan(/<value>(.*)<\/value>/) do |x| 
    puts x 
end 
+2

Анализ XML с помощью регулярных выражений - это плохая практика и склонность к ошибкам. См. Ответ: http://stackoverflow.com/a/1768230/99266 –

+0

Наконец-то настоящий ответ на вопрос для тех из нас, кто может доверять нашему вкладу, а не использовать большой молот LOL – rogerdpack

1

Как только побочный комментарий, для этого конкретного приложения он может чувствовать себя трудно, но обучение Nokogiri или Libxml может он lp вы принимаете решение о более сложном анализе XML по строке. Кроме того, синтаксический анализ XML в Ruby действительно довольно тривиальный в наши дни и делает это. Правильный путь, по крайней мере, упростит его распространение до нетривиального метода, когда ваш клиент в конечном итоге попросит вас сделать что-то смехотворно вне сферы действия, которая включает полный анализ XML. :)

Для других платформ и технологий я, вероятно, не рекомендовал бы такие инвестиции, но Nokogiri безболезнен. И если вам просто хочется играть, вы можете попробовать Hpricot и получить свою дозу _why на день (RIP).

+0

+1 для [Nokogiri] (http : //nokogiri.org). Я бы рекомендовал его по Hpricot; Аксессоры очень похожи, но Nokogiri более надежный. –

0

Я не вижу причины использовать регулярное выражение вместо реального парсера. Простота использования является ужасным оправданием, что не подтвердится:

require 'nokogiri' 

doc = Nokogiri::XML(<<EOT) 
<?xml version="1.0"?> 
<methodCall> 
    <methodName>weblogUpdates.extendedPing</methodName> 
    <params> 
    <param> 
     <value>Official Google Blog</value> 
    </param> 
    <param> 
     <value>http://googleblog.blogspot.com/</value> 
    </param> 
    <param> 
     <value>http://googleblog.blogspot.com/</value> 
    </param> 
    <param> 
     <value>http://googleblog.blogspot.com/atom.xml</value> 
    </param> 
    </params> 
</methodCall> 
EOT 

puts doc.search('value').map(&:text) 

Запуск, что выходы:

Official Google Blog 
http://googleblog.blogspot.com/ 
http://googleblog.blogspot.com/ 
http://googleblog.blogspot.com/atom.xml 

Если есть необходимость быть более конкретным, детализация с более конкретным CSS путь:

doc.search('param value') 

Использование регулярных выражений, таких как %r(<value>(.*)</value>) будет «Splode, если содержащийся текст содержит "</value>" и улавливать те ситуации, ныряет вниз очень глубокий г abbit отверстие.

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