2009-11-20 43 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學生都會在他/她的職業生涯中的某個時間在某些家庭作業或其他任務中證明了這種不可能性。 – 2009-11-20 04:50:27

+2

@Jörg - 我恐怕你和我在談論兩件完全不同的事情。數學上的不可能性與真正的不可能性是非常不同的(因爲缺乏更好的短語)。在XML上使用正則表達式是不可能的?不,當然不是 - 完全有可能使用正則表達式來破解大多數情況下都能正常工作的解決方案。我理解你的觀點(並且原則上同意你的觀點),但是對於像這樣的實際討論確實沒有多大的意義。 – 2009-11-21 14:40:41

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 – 2012-03-22 15:16:02

+0

最後一個真正的答案,我們這些人可以相信我們的輸入,而不是使用大錘子[Lok – rogerdpack 2016-10-02 01:00:50

1

只是一個側面評論,對於這個特定的應用程序可能感到困難,但學習引入nokogiri或libxml的可能,他您可以決定更復雜的XML解析。此外,現在在Ruby中解析XML確實非常微不足道,而正確的做法至少可以讓您輕鬆擴展爲非平凡的方法,當您的客戶端最終要求您在範圍之外做一些可笑的事情時,就會涉及到完整的XML解析。 :)

對於其他框架和技術,我可能不會推薦這樣的投資,但Nokogiri是無痛的。如果你只是想玩,你可以嘗試一下Hpricot,並在一天中獲得你的劑量(RIP)。

+0

+1] [Nokogiri](http ://nokogiri.org)。我會把它推薦給Hpricot;訪問器非常相似,但Nokogiri更加強大。 – 2010-12-14 10:25:40

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>"和誘捕那些情況下潛水非常深刻的[R abbit洞。