Recently, I need to retrieve the default namespace from an incoming message such as:
<message xmlns="Message" a="1" b="2">
<request>
<text xmlns="Text" a="1">ok</text>
</request>
</message>
With a message like the above, I want to retrieve the namspace Text from the text element.
One method I was able to leverage was using Groovy's DOMBuilder and DOMCategory to read the message and retrieve the namespace:
import groovy.xml.DOMBuilder
import groovy.xml.dom.DOMCategory
def xml = """<message xmlns="Message" a="1" b="2">
<request>
<text xmlns="Text" a="1">ok</text>
</request>
</message>"""
def reader = new StringReader(xml)
def doc = DOMBuilder.parse(reader)
def root = doc.documentElement
def ns
use(DOMCategory) {
ns = root['request']['text'].'@xmlns'[0]
}
println "ns=$ns"
Output:
ns=Text
Omitting the lookup of the first element, we would get a list:
ns = root['request']['text'].'@xmlns'
Output:
ns=["Text"]
This could be used to get a list of all attribute value for an element.
Another method is to use XMLParser:
def doc = new XmlParser(false, false).parseText(xml)
def ns = doc.'request'.'text'.'@xmlns'
def doc = new XmlSlurper(false, false).parseText(xml)
def ns = doc.'request'.'text'.'@xmlns'
Both methods requiring making the XML reader namespace unaware with the following constructors:
XmlSlurper(boolean validating, boolean namespaceAware)
XmlParser(boolean validating, boolean namespaceAware)
I'm sure there are plenty of other methods to do the same, if you have one please feel free to leave a comment.
Why did you want the text of the namespace attribute? In XPath/XSLT if I wanted to base logic on the namespace, I'd use pattern matching against the namespace.
ReplyDeleteI posted an example.
The output is:
Cool person says:
This is totally cool.
Yeah I'm no good at these games.
Geeky person says:
Oops, I'm not cool.
Awesome, now I'm kind of cool.
Thanks for the example.
ReplyDeleteIn the case was working on, a Mule transformer, I did need to have logic based on the value of the namespace. Most of our transformers are in Groovy so I wanted to see if it could be done, easily or not.