2

我需要在 Ruby on Rails 中使用 Nokogiri 读取 XML 文件并生成 SOAP 请求正文。

我需要生成的请求正文是:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:c2="http://c2_0.customer.webservices.csx.dtv.com/">
  <soapenv:Header>
    <soapenv:Body>
      <c2:getCustomer>
        <customerId>10</customerId>
        <UserId>adminUser</UserId>
      </c2:getCustomer>
    </soapenv:Body>
  </soapenv:Header>
</soapenv:Envelope>

我正在使用这段代码:

require 'nokogiri'

doc = Nokogiri::XML(File.open('p_l_s.xml')) 

wsID =doc.xpath('//transaction:WsID' , 'transaction'  => 'http://www.nrf-arts.org/IXRetail/namespace/').inner_text

builder = Nokogiri::XML::Builder.new do |xml|
  xml.Envelope("xmlns:soapenv" => "http://schemas.xmlsoap.org/soap/envelope/",
               "xmlns:c2" => "http://c2_0.customer.webservices.csx.dtv.com/") do
      xml.parent.namespace = xml.parent.namespace_definitions.first
      xml['soapenv'].Header {
        xml.Body {
          xml['c2'].getCustomer{
            #xml.remove_namespaces!     
            xml.customerId wsID
            xml.UserId "adminUser"    
        }
      }
    }
  end
end
puts builder.to_xml

而且,当从 Ubuntu 的终端执行它时,我得到:

<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:c2="http://c2_0.customer.webservices.csx.dtv.com/">
  <soapenv:Header>
    <soapenv:Body>
      <c2:getCustomer>
        <c2:customerId>10</c2:customerId>
        <c2:UserId>adminUser</c2:UserId>
      </c2:getCustomer>
    </soapenv:Body>
  </soapenv:Header>
</soapenv:Envelope>

我得到了c2XML 元素的名称空间,customerIdUserId对于我在将要调用的 WSDL 文件中调用的方法来说不是必需的。

4

2 回答 2

1

我能够使用以下代码生成您需要的输出:

builder = Nokogiri::XML::Builder.new do |xml|
  xml.Envelope("xmlns:soapenv" => "http://schemas.xmlsoap.org/soap/envelope/",
               "xmlns:c2" => "http://c2_0.customer.webservices.csx.dtv.com/") do
    xml.parent.namespace = xml.parent.namespace_definitions.first
    xml.Header {
      xml.Body {
        xml.getCustomer {     
          xml.customerId {
            xml.parent.content=(wsID)
            xml.parent.namespace = xml.parent.namespace_definitions.first
          }
          xml.UserId{
            xml.parent.content=("adminUser")
            xml.parent.namespace = xml.parent.namespace_definitions.first
          } 
          xml.parent.namespace = xml.parent.namespace_scopes[1]
        }
      }
    }
  end
end
puts builder.to_xml

在到达“getCustomer”之前,您不必显式设置名称空间。结合 'content' 和 'namespace_definition' 方法,您可以指定子节点的命名空间和内容 - 这应该会输出您要查找的内容。

Builder 的 Nogokiri 页面:http://nokogiri.org/Nokogiri/HTML/Builder.htmlNode:http ://nokogiri.org/Nokogiri/XML/Node.html非常有用,希望有助于阐明更多信息在这给你。

于 2013-08-09T02:49:31.810 回答
1

我认为 Mel T 的回答中的这段代码:

xml.customerId {
  xml.parent.content=(wsID)
  xml.parent.namespace = xml.parent.namespace_definitions.first
}

会输出:

<soapenv:customerId>10</soapenv:customerId>

我这样做了:

xml.customerId {
  xml.parent.content=(wsID)
  xml.parent.namespace = nil
}
于 2015-03-10T10:53:24.423 回答