2014-03-25 66 views
0

我想解析下面的XML來獲取電子郵件地址。我可以得到messageid,但我認爲有一個:在前面讓我使用xpath。不知道如何提取電子郵件地址。我想試圖解析與nokogiri和紅寶石xml

xml.xpath( 「// S:身體/發現/請求/ EmailAddress的」)。children.text.to_s

xml.xpath(「// S:身體/Discover/EmailAddress").children.text.to_s

如果我做xml.xpath(「// s:Body」)。children.text.to_s我得到的電子郵件和所有的新行和標籤的版本但我不想解析電子郵件,如果我不必。

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 
    <s:Header> 
     <a:Action s:mustUnderstand="1">test url</a:Action> 
     <a:MessageID>mid</a:MessageID> 
     <a:ReplyTo> 
      <a:Address>test url</a:Address> 
     </a:ReplyTo> 
     <a:To s:mustUnderstand="1">test url</a:To> 
    </s:Header> 
    <s:Body> 
     <Discover xmlns="test url"> 
      <request xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
       <EmailAddress>[email protected]</EmailAddress> 
       <RequestVersion>1.0</RequestVersion> 
      </request> 
     </Discover> 
    </s:Body> 
</s:Envelope> 
+0

https://amolnpujari.wordpress.com/2012/03/31/reading_huge_xml-rb我發現比引入nokogiri快牛的5倍,在牛,因此這裏一個例子 - https://gist.github.com/amolpujari/5966431,搜索任何元素並以散列形式獲取它 –

回答

1

test url是防止引入nokogiri的Xpath的距離內s:Body捕捉到您的命名空間。嘗試簡單

email = xml.xpath("//s:Body").first.to_xml.scan(/<EmailAddress>([^<]+)/)[0][0] 
0

Discover元素(及其子女)在不同的命名空間,你需要在查詢中指定。 xpath method的第二個參數是一個散列,您可以將查詢中使用的前綴與命名空間url關聯起來。看看section on namespaces in the Nokogiri tutorial

使用Nokogiri,如果您不指定命名空間散列,它會自動註冊在根節點上爲您定義的所有命名空間。在這種情況下,http://www.w3.org/2005/08/addressing的前綴爲ahttp://www.w3.org/2003/05/soap-envelope的前綴爲s。這就是爲什麼您的查詢//s:Body有效。 Discover的名稱空間聲明不在根上,因此您必須自己註冊它。

當您提供自己的名稱空間散列時,Nokogiri不會添加在根上定義的名稱,因此您還需要包含查詢中使用的任何名稱空間。

在你的情況下,以下將找到EmailAddress節點。只要URI匹配,您使用的實際前綴無關緊要(這裏我選擇了t)。

xml.xpath('//s:Body/t:Discover/t:request/t:EmailAddress', 
    's' => "http://www.w3.org/2003/05/soap-envelope", 
    't' => "test url")