我需要在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>
我获得了XML元素c2
和customerId
的{{1}}命名空间,这是我将要调用的WSDL文件中调用的方法所不需要的。
答案 0 :(得分: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'方法的组合,您可以指定子节点的名称空间和内容 - 它们应该输出您要查找的内容。
构建器的Nogokiri页面:http://nokogiri.org/Nokogiri/HTML/Builder.html和节点:http://nokogiri.org/Nokogiri/XML/Node.html非常有用,希望能帮助您更好地了解这一点。
答案 1 :(得分: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
}