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:
这会创建如下XML:
<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:
如果没有我的所有namespace_definitions hackery - XML会像这样出现:
<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.
我有这个带有安全元素的头部分需要带有命名空间的格式,但是一旦我们点击了Request部分(以及任何后续部分,或者使用这个特定API执行不同操作的任何其他NodeSet ......)文档调用对于非命名空间的元素。
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)?
简单的问题是:如何生成嵌套在具有命名空间定义的父元素内的NodeSet,而不继承父命名空间(没有我放在一起的恶心黑客)?
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.
这样我就可以将这个标题部分(所有消息都需要)抽象到它自己的方法中,并在不同的主体部分上缝合通过API公开的功能。
Please help!
1 个解决方案
#1
3
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.
使用< <运算符将原始字符串附加到文档。还要注意#doc.root的使用,如果你只是使用#to_xml,你会在字符串的开头得到 。
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.
但是,如果希望Request是命名空间但不是它的孩子,这种方法并不理想,因为你必须为每个孩子使用一个构建器(一个构建器只能有一个root。)多个“根”的解决方案是使用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>
#1
3
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.
使用< <运算符将原始字符串附加到文档。还要注意#doc.root的使用,如果你只是使用#to_xml,你会在字符串的开头得到 。
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.
但是,如果希望Request是命名空间但不是它的孩子,这种方法并不理想,因为你必须为每个孩子使用一个构建器(一个构建器只能有一个root。)多个“根”的解决方案是使用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>