First - check out this train wreck of code:
xml['soapenv'].Body {
xml.Request {
xml.version ("1.1") {
xml.parent.namespace = xml.parent.namespace_definitions.first
}
xml.name (@admin_name.name) {
xml.parent.namespace = xml.parent.namespace_definitions.first
}
xml.source_version ("1.0") {
xml.parent.namespace = xml.parent.namespace_definitions.first
}
xml.downloadmarked ("0") {
xml.parent.namespace = xml.parent.namespace_definitions.first
}
xml.from (@dateFrom) {
xml.parent.namespace = xml.parent.namespace_definitions.first
}
xml.time_from ("0000") {
xml.parent.namespace = xml.parent.namespace_definitions.first
}
xml.to (@dateTo) {
xml.parent.namespace = xml.parent.namespace_definitions.first
}
xml.time_to ("2359") {
xml.parent.namespace = xml.parent.namespace_definitions.first
}
xml.limit ("100") {
xml.parent.namespace = xml.parent.namespace_definitions.first
}
xml.parent.namespace = xml.parent.namespace_definitions.first
}
}
This creates XML like this:
<soapenv:Body>
<Request>
<version>1.1</version>
<name>COMPANY NAME HERE</name>
<source_version>1.0</source_version>
<downloadmarked>0</downloadmarked>
<from>20140125</from>
<time_from>0000</time_from>
<to>20140125</to>
<time_to>2359</time_to>
<limit>100</limit>
</Request>
</soapenv:Body>
Without all my namespace_definitions hackery - the XML would come out like this:
<soapenv:Body>
<soapenv:Request>
<soapenv:version>1.1</soapenv:version>
<soapenv:name>COMPANY NAME HERE</soapenv:name>
<soapenv:source_version>1.0</soapenv:source_version>
<soapenv:downloadmarked>0</soapenv:downloadmarked>
<soapenv:from>20140125</soapenv:from>
<soapenv:time_from>0000</soapenv:time_from>
<soapenv:to>20140125</soapenv:to>
<soapenv:time_to>2359</soapenv:time_to>
<soapenv:limit>100</soapenv:limit>
</soapenv:Request>
</soapenv:Body>
I've got this header portion with security elements that require the format with the namespace, but once we hit the Request portion (and any subsequent portion, or any other NodeSet which does different things with this particular API...) the documentation calls for non-namespaced elements.
The simple question is: How do I generate a NodeSet nested inside a parent element that has a namespace definition, without inheriting the namespace of the parent (without the disgusting hack that I've put together)?
I'm using the common:
builder = Nokogiri::XML::Builder.new do |xml|
And what I'm really interested in is how I can take 'builder' and do something like:
el = builder.at_xpath('//Body')
newEl = Nokogiri::XML::Node.new do |node|
...my node stuff here...
end
el.add_child(newEl)
So that I could abstract this header portion (required for all messages) into it's own method and stitch on the different body portions for the functionalities exposed via the API.
Please help!
You can accomplish that by using an additional builder.
xml['soapenv'].Body do
xml << Nokogiri::XML::Builder.new do |request_xml|
xml.Request do
request_xml.version "1.1"
request_xml.name @admin_name.name
request_xml.source_version "1.0"
request_xml.downloadmarked "0"
request_xml.from @dateFrom
request_xml.time_from "0000"
request_xml.to @dateTo
request_xml.time_to "2359"
request_xml.limit "100"
end
end.doc.root.to_xml
end
will result in:
<soapenv:Body>
<Request>
<version>1.1</version>
<name>COMPANY NAME HERE</name>
<source_version>1.0</source_version>
<downloadmarked>0</downloadmarked>
<from>20140125</from>
<time_from>0000</time_from>
<to>20140125</to>
<time_to>2359</time_to>
<limit>100</limit>
</Request>
</soapenv:Body>
Using the <<
operator appends raw string to the document. Also note the use of #doc.root
, if you just use #to_xml
you'll get <?xml version="1.0"?>
at the beginning of the string.
However if Request
was desired to be namespaced but not it's children this approach wouldn't be ideal because you'd have to use a builder for each child (a builder can have only 1 root.) A solution for multiple "roots" is to use a DocumentFragment.
xml['soapenv'].Body do
request = Nokogiri::XML::DocumentFragment.parse ""
Nokogiri::XML::Builder.with(request) do |request_xml|
request_xml.version "1.1"
request_xml.name @admin_name.name
request_xml.source_version "1.0"
request_xml.downloadmarked "0"
request_xml.from @dateFrom
request_xml.time_from "0000"
request_xml.to @dateTo
request_xml.time_to "2359"
request_xml.limit "100"
end
xml.Request << request.to_xml
end
will result in:
<soapenv:Body>
<soapenv:Request>
<version>1.1</version>
<name>COMPANY NAME HERE</name>
<source_version>1.0</source_version>
<downloadmarked>0</downloadmarked>
<from>20140125</from>
<time_from>0000</time_from>
<to>20140125</to>
<time_to>2359</time_to>
<limit>100</limit>
</soapenv:Request>
</soapenv:Body>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With