I'm trying to use XPath to extract some values from an XML Response Payload. I have validated the XPath elsewhere, but for some reason, it doesn't appear to be working at runtime in Apigee.
XML Payload:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn:xtk:session" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <LogonResponse xmlns="urn:xtk:session" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <pstrSessionToken xsi:type="xsd:string">___xxx</pstrSessionToken> <pSessionInfo xsi:type="ns:Element" SOAP-ENV:encodingStyle="http://xml.apache.org/xml-soap/literalxml"> <sessionInfo> <serverInfo advisedClientBuildNumber="xx" allowSQL="false" buildNumber="xx" databaseId="xxx" defaultNameSpace="xxx" instanceName="xxx" majNumber="6" minClientBuildNumber="xx" minNumber="0" minNumberTechnical="0" securityTimeOut="xx" serverDate="xxx" servicePack="1" sessionTimeOut="xxx" /> <userInfo datakitInDatabase="true" homeDir="" instanceLocale="en-US" locale="en-US" login="xxx" loginCS="xxx" loginId="xxx" noConsoleCnx="false" orgUnitId="0" theme="" timezone="Europe/London"> <login-group id="xxx" /> <login-right right="admin" /> <installed-package name="core" namespace="acx" /> </userInfo> </sessionInfo> </pSessionInfo> <pstrSecurityToken xsi:type="xsd:string">@xxx==</pstrSecurityToken> </LogonResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
The Extract Variable Policy:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ExtractVariables async="false" continueOnError="false" enabled="true" name="EV-ExtractAdobeSessionID"> <DisplayName>EV-ExtractAdobeSessionID</DisplayName> <Source clearPayload="false">adobe.logonResponse.content</Source> <VariablePrefix>adobe</VariablePrefix> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <XMLPayload stopPayloadProcessing="true"> <Namespaces> <Namespace prefix="ns">urn:xtk:session</Namespace> <Namespace prefix="xsd">http://www.w3.org/2001/XMLSchema</Namespace> <Namespace prefix="xsi">http://www.w3.org/2001/XMLSchema-instance</Namespace> <Namespace prefix="SOAP-ENV">http://schemas.xmlsoap.org/soap/envelope</Namespace> </Namespaces> <Variable name="session" type="string"> <XPath>/SOAP-ENV:Envelope/SOAP-ENV:Body/LogonResponse/pstrSessionToken/text()</XPath> </Variable> <Variable name="security" type="string"> <XPath>/SOAP-ENV:Envelope/SOAP-ENV:Body/LogonResponse/pstrSecurityToken/text()</XPath> </Variable> </XMLPayload> </ExtractVariables>
I would appreciate any help in figuring out why my XPath isn't resolving.
Please note:
Solved! Go to Solution.
ok, I see three problems.
The soap namespace in the response document is http://schemas.xmlsoap.org/soap/envelope/ . Note the trailing slash. In your policy configuration, you have
<Namespace prefix="SOAP-ENV">http://schemas.xmlsoap.org/soap/envelope</Namespace>
There is no trailing slash here. That means it is a totally different namespace. Add the slash to the namespace declaration in the policy configuration, to fix this problem.
<LogonResponse xmlns="urn:xtk:session"
That xmlns='...' thing says "this element falls within this namespace. That means if you use an xpath to refer to that element, you need to specify the namespace prefix. But your xpath lacked a prefix for this element. Likewise for the pstrSessionToken element. You had this:
<XPath>/SOAP-ENV:Envelope/SOAP-ENV:Body/LogonResponse/pstrSessionToken/text()</XPath>
you want this:
<XPath>/SOAP-ENV:Envelope/SOAP-ENV:Body/ns:LogonResponse/ns:pstrSessionToken/text()</XPath>
And you need to make the similar change for the second XPath.
Also, in case you were not aware, the XML namespace prefixes that you use in xpath are not syntactically important. The important thing is the referent of the prefix. You can use a different prefix in your xpath, than appears in the actual XML document, as long as the respective prefixes refer to the same xml namespace string (even down to the last trailing slash!). Also, while the namespaces with prefixes like xsi and xsd are present in the original document, those namespaces are not used by either of your xpaths. So you can omit them from the policy configuration. With all of those changes, this policy configuration, where I use soap as the prefix instead of SOAP-ENV for the soap namespace, works fine:
<ExtractVariables name='EV-ExtractAdobeSessionID'> <Source>my_message_variable</Source> <VariablePrefix>adobe</VariablePrefix> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <XMLPayload> <Namespaces> <Namespace prefix="ns">urn:xtk:session</Namespace> <Namespace prefix="soap">http://schemas.xmlsoap.org/soap/envelope/</Namespace> </Namespaces> <Variable name="session" type="string"> <XPath>/soap:Envelope/soap:Body/ns:LogonResponse/ns:pstrSessionToken/text()</XPath> </Variable> <Variable name="security" type="string"> <XPath>/soap:Envelope/soap:Body/ns:LogonResponse/ns:pstrSecurityToken/text()</XPath> </Variable> </XMLPayload> </ExtractVariables>
I cannot show you my results, because for some reason the image upload widget is not working today. But trust me, it's working !
--
You said that your xpath worked fine outside of Apigee Edge. I think maybe you have used a slightly different configuration - different namespaces and maybe different prefixes - if that is the case. For sure, the suggestions and corrections I offered above are standard XPath and XML Namespace things; they are not peculiar to Apigee Edge. A compliant XPath evaluator would need the same adjustments.
If you have any questions about any of this, let me know!