试图用nokogiri和ruby解析xml

时间:2014-03-25 04:55:22

标签: ruby xml nokogiri

我正在尝试解析下面的xml以获取电子邮件地址。我可以得到messageid,但我认为在前面使用a:允许我使用xpath。不确定如何提取电子邮件地址。我正在尝试

xml.xpath(" // S:车身/查询/请求/ EmailAddress的&#34)。children.text.to_s

xml.xpath(" // S:车身/查询/ EmailAddress的&#34)。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>bob@xml.com</EmailAddress> 
                <RequestVersion>1.0</RequestVersion> 
            </request> 
        </Discover> 
    </s:Body> 
</s:Envelope>

2 个答案:

答案 0 :(得分:1)

test url阻止了Nokogiri的Xpath攻击s:Body内的命名空间。试试吧

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

答案 1 :(得分:0)

Discover元素(及其子元素)位于不同的命名空间中,您需要在查询中指定它。 xpath method的第二个参数是一个散列,您可以将查询中使用的前缀与名称空间URL相关联。看看section on namespaces in the Nokogiri tutorial

使用Nokogiri,如果您没有指定命名空间哈希,它将自动注册根节点上定义的任何命名空间。在这种情况下,a的{​​{1}}前缀和http://www.w3.org/2005/08/addressing的{​​{1}}前缀。这就是您对s的查询有效的原因。 http://www.w3.org/2003/05/soap-envelope的名称空间声明不在根目录下,因此您必须自己注册。

当您提供自己的命名空间哈希时,Nokogiri不会添加在根目录中定义的那些,因此您还需要包含查询中使用的任何一个。

在您的情况下,以下内容将找到//s:Body节点。您使用的实际前缀无关紧要(此处我选择了Discover),只要URI匹配)。

EmailAddress