为什么Nokogiri的xpath不按预期工作?

时间:2015-12-23 00:20:50

标签: ruby xpath nokogiri

我正在使用Nokogiri解析Soap响应,但出于某种原因,APP_ROOT/tmp/cache/assetsxpath方法找不到css标记之外的任何标记。

我想解析的XML是

<soap:Body>

如果我用调试器检查解析的XML,我会看到

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <AuthenticationResponse xmlns="http://tempuri.org/">
            <AuthenticationResult>
                <SessionID>clinTQYART6qxeQ%k^Am&amp;Sd5Co3</SessionID>
                <RequestStatus>1</RequestStatus>
                <RequestMessage>Success</RequestMessage>
            </AuthenticationResult>
        </AuthenticationResponse>
    </soap:Body>
</soap:Envelope>

这很好。

=> #(Document:0x3fce3c4dd95c { name = "document", children = [ #(Element:0x3fce385b04dc { name = "Envelope", namespace = #(Namespace:0x3fce385b04b4 { prefix = "soap", href = "http://schemas.xmlsoap.org/soap/envelope/" }), children = [ #(Element:0x3fce385e509c { name = "Body", namespace = #(Namespace:0x3fce385b04b4 { prefix = "soap", href = "http://schemas.xmlsoap.org/soap/envelope/" }), children = [ #(Element:0x3fce385e4c64 { name = "AuthenticationResponse", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Element:0x3fce385e48a4 { name = "AuthenticationResult", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Element:0x3fce385e44f8 { name = "SessionID", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Text "clinTQYART6qxeQ%k^Am&Sd5Co3")] }), #(Element:0x3fce39dcff7c { name = "RequestStatus", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Text "1")] }), #(Element:0x3fce39dcfa2c { name = "RequestMessage", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Text "Success")] })] })] })] })] })] }) 给出了xml.xpath("//SessionID")

然而[]给出了

xml.xpath("//soap:Body")[0]

=> #(Element:0x3fce385e509c { name = "Body", namespace = #(Namespace:0x3fce385b04b4 { prefix = "soap", href = "http://schemas.xmlsoap.org/soap/envelope/" }), children = [ #(Element:0x3fce385e4c64 { name = "AuthenticationResponse", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Element:0x3fce385e48a4 { name = "AuthenticationResult", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Element:0x3fce385e44f8 { name = "SessionID", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Text "clinTQYART6qxeQ%k^Am&Sd5Co3")] }), #(Element:0x3fce39dcff7c { name = "RequestStatus", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Text "1")] }), #(Element:0x3fce39dcfa2c { name = "RequestMessage", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Text "Success")] })] })] })] }) 给出了

xml.xpath("//soap:Body")[0].children[0].children[0].children[0]

因此=> #(Element:0x3fce385e44f8 { name = "SessionID", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Text "clinTQYART6qxeQ%k^Am&Sd5Co3")] }) 为我提供了正确的id字符串。

那么为什么xml.xpath("//soap:Body")[0].children[0].children[0].children[0].content不起作用?

2 个答案:

答案 0 :(得分:1)

这是因为SessionID位于命名空间http://tempuri.org/

尝试类似(未经测试)的内容:

xml.xpath("//x:SessionID", {"x" => "http://tempuri.org/"})

答案 1 :(得分:0)

不是您问题的直接答案,但如果您想要解析SOAP,那么最好使用savon gem而不是nokogiri。它专门用于处理所有复杂的SOAP。