Created
June 7, 2010 09:29
-
-
Save mudge/428455 to your computer and use it in GitHub Desktop.
Namespaces with Nokogiri::Builder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Dealing with namespaces in Nokogiri. | |
# | |
# First thing you must do is abandon what you're used to with Builder, | |
# namespaces aren't just attributes on an element, they uniquely identify | |
# what sort of element you are building and, as such, you are better off | |
# specifying them manually. | |
# | |
# The key here is accessing the Nokogiri::XML::Element being built with | |
# b.parent, then you can set the namespace (distinguished by an element | |
# with a prefix such as "soap12:Envelope") or add a default namespace | |
# (where there is no prefix but an "xmlns" attribute). | |
# | |
# The example below shows both types of namespaces being created and used | |
# including setting a namespace on the root element of a document. | |
# | |
# Thanks to http://stackoverflow.com/questions/1829425/creating-an-xml-document-with-a-namespaced-root-element-with-nokogiri-builder | |
# for pointing me in the right direction. | |
b = Nokogiri::XML::Builder.new | |
b.Envelope("xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema") { | |
b.parent.namespace = b.parent.add_namespace_definition("soap12", "http://www.w3.org/2003/05/soap-envelope") | |
b['soap12'].Body { | |
b.Foo { | |
b.parent.default_namespace = "http://FOO/Bar" | |
b.exampleXML { | |
b.example("xsi:schemaLocation" => "http://www.example.com/schemas https://service.example.com/FOO/schemas/monkey.xsd") { | |
b.parent.add_namespace_definition("xsi", "http://www.w3.org/2001/XMLSchema-instance") | |
b.parent.default_namespace = "http://www.example.com/schemas" | |
b.dummy("Test") | |
b.domain("woo") | |
b.person { | |
b.name("test") | |
} | |
} | |
} | |
} | |
} | |
} | |
# This will create the following XML: | |
# | |
# <?xml version="1.0"?> | |
# <soap12:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> | |
# <soap12:Body> | |
# <Foo xmlns="http://FOO/Bar"> | |
# <exampleXML> | |
# <example xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.example.com/schemas" xsi:schemaLocation="http://www.example.com/schemas https://service.example.com/FOO/schemas/monkey.xsd"> | |
# <dummy>Test</dummy> | |
# <domain>woo</domain> | |
# <person> | |
# <name>test</name> | |
# </person> | |
# </example> | |
# </exampleXML> | |
# </Foo> | |
# </soap12:Body> | |
# </soap12:Envelope> | |
# | |
# Now that it's all namespaced properly, don't forget how to select | |
# elements with XPath: http://tenderlovemaking.com/2009/04/23/namespaces-in-xml/ | |
# | |
# n = Nokogiri::XML(b.to_xml) | |
# n.xpath("//n:Foo", "xmlns:n" => "http://FOO/Bar") | |
# n.xpath("//n:dummy", "xmlns:n" => "http://www.example.com/schemas") | |
# n.xpath("//n:person/n:name", "xmlns:n" => "http://www.example.com/schemas") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I don't think you really need the "parent" hack. Check this out:
it creates this xml: