I have a proxy that receives a xml payload of this format
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>string</wsse:Username>
<wsse:Password>string</wsse:Password>
<wsse:Nonce EncodingType="string">string</wsse:Nonce>
<wsu:Created>string</wsu:Created>
</wsse:UsernameToken>
<wsu:Timestamp wsu:Id="string">
<wsu:Created>string</wsu:Created>
<wsu:Expires>string</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<GetXdata_IN xmlns="com.abc.def.getxdata">
<Code>K</Code>
</GetXdata_IN>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I'm using the EV policy to extract the <Code>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="EV-Code">
<DisplayName>EV-Code</DisplayName>
<Source>request</Source>
<XMLPayload stopPayloadProcessing="false">
<Namespaces>
<Namespace prefix="ns0">com.abc.def.getxdata</Namespace>
</Namespaces>
<Variable name="Code" type="string">
<XPath>//ns0:GetXdata_IN/ns0:Code</XPath>
</Variable>
</XMLPayload>
</ExtractVariables>
But this breaks when I receive the XML with namespace like
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>string</wsse:Username>
<wsse:Password>string</wsse:Password>
<wsse:Nonce EncodingType="string">string</wsse:Nonce>
<wsu:Created>string</wsu:Created>
</wsse:UsernameToken>
<wsu:Timestamp wsu:Id="string">
<wsu:Created>string</wsu:Created>
<wsu:Expires>string</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<GetXdata_IN xmlns_tns="com.abc.def.getxdata">
<Code>K</Code>
</GetXdata_IN>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
How do I manage to read the <Code> element irrespective of the namespace /prefix
Like I could get it as
<GetXdata_IN xmlns_tns="com.abc.def.getxdata">
OR
<GetXdata_IN xmlns_tnsinput="com.abc.def.getxdata">
@dchiesa1
Please advise.
Solved! Go to Solution.
Yes. Though we all may not like it, the rules around XML namespaces are clearly defined and strict. The upshot is that this:
<GetXdata_IN xmlns="com.abc.def.getxdata">
..is intended to convey a different meaning than this:
<GetXdata_IN xmlns_tns="com.abc.def.getxdata">
...and the various XML tools and technologies that support XML namespaces, including XPath, recognize that fact. The former is an element in the com.abc.def.getxdata
namespace. The latter is an element in the "default" namespace, which... is determined by the parent hierarchy. In your example the default namespace for that element was -none-.
BTW, this statement of yours is not sensible:
when I receive the XML with namespace like
You were referring to the latter XML fragment I showed above. The attribute xmlns_tns does not convey a namespace. It has no meaning, w.r.t. XML namespaces. It looks like it could be a namespace declaration. It looks pretty similar. But it's not a namespace declaration, so you are not actually "receiving" the namespace.
I think you could use something like this as your expression, to focus just on the element name, and ignore the namespace altogether:
<ExtractVariables async="false" continueOnError="false" enabled="true" name="EV-Code">
<DisplayName>EV-Code</DisplayName>
<Source>request</Source>
<XMLPayload stopPayloadProcessing="false">
<Namespaces>
<Namespace prefix="soap">http://schemas.xmlsoap.org/soap/envelope/</Namespace>
</Namespaces>
<Variable name="Code" type="string">
<XPath>//soap:Body/*[local-name()='GetXdata_IN']/*[local-name()='Code']/text()</XPath>
</Variable>
</XMLPayload>
</ExtractVariables>
That will "work" for the scenario you described but it feels unhygienic to me. The real problem is if you have a downstream system that is generating XML that can take either of those two forms that you mentioned, something is broken there. It shouldn't do that. I would want to fix the problem there, rather than configure Apigee to adapt to the inconsistency. I hope this is clear.