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



我正在用Nokogiri解析Soap响应,但由于某种原因,xpathcss方法找不到<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>

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

=> #(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")] })]
          })]
      })]
  })

CCD_ 7给出

=> #(Element:0x3fce385e44f8 { name = "SessionID", namespace = #(Namespace:0x3fce385e4c14 { href = "http://tempuri.org/" }), children = [ #(Text "clinTQYART6qxeQ%k^Am&Sd5Co3")] })

并且因此CCD_ 8给了我正确的id字符串。

那么为什么xml.xpath("//SessionID")不起作用呢?

这是因为SessionID在名称空间http://tempuri.org/中。

尝试类似(未经测试):

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

这不是您问题的直接答案,但如果您想解析SOAP,最好使用savongem而不是nokogiri。它是专门为处理SOAP的所有复杂性而设计的。

相关内容

  • 没有找到相关文章

最新更新