2014-03-25 32 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")