I am trying to fetchthe value of attribute xmlns inside CanOfferProductResponse tag in Groovy
below is my XML-
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body><CanOfferProductResponse xmlns="urn:iQQ:API:22:iQQMessages.xsd"/></SOAP-ENV:Body></SOAP-ENV:Envelope>
I tried below code but it's not working
def Envelope = new XmlSlurper().parseText(xml)
println Envelope.Body.CanOfferProductResponse.@xmlns
// expected output = urn:iQQ:API:22:iQQMessages.xsd (which is inside Tag)
I am new to XML, please help me.
The use of XML namespaces is complicating matters perhaps. If you know that the XML snippet is using the exact namespace prefixes as shown, you can disable namespace awareness in the XmlSlurper and use the "prefix:elementName" as to reference the elements.
def xml = '''<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SOAP-ENV:Body>
<CanOfferProductResponse xmlns="urn:iQQ:API:22:iQQMessages.xsd"/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
'''
// the second constructor argument controls namespace awareness
def env = new XmlSlurper(false, false).parseText(xml)
def namespace = env.'SOAP-ENV:Body'.CanOfferProductResponse.@xmlns
assert namespace == 'urn:iQQ:API:22:iQQMessages.xsd'
But if the default namespace is not always defined on the CanOfferProductResponse
element or if the namespace prefixes are not always consistent, e.g. the Envelope element has a xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
attribute instead of an xmlns:SOAP-ENV=...
, then this approach would not work.
A namespace-aware approach would involve calling the lookupNamespace
method passing in an empty String argument (which means the default namespace for that element):
// by default, XmlSlurper instances are namespace aware
def env = new XmlSlurper().parseText(xml)
def namespace = env.Body.CanOfferProductResponse.lookupNamespace('')
assert namespace == 'urn:iQQ:API:22:iQQMessages.xsd'
But since namespaces are inherited, this approach means that the lookupNamespace
method would still return 'urn:iQQ:API:22:iQQMessages.xsd' even if there wasn't physically an xmlns
attribute on the CanOfferProductResponse
element, e.g.
def xml = '''<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="urn:iQQ:API:22:iQQMessages.xsd">
<SOAP-ENV:Body>
<CanOfferProductResponse />
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
'''
def env = new XmlSlurper().parseText(xml)
def namespace = env.Body.CanOfferProductResponse.lookupNamespace('')
assert namespace == 'urn:iQQ:API:22:iQQMessages.xsd'
(This sample was executed with Groovy 2.5)