Extract Variable : Xpath for Soap request . Not able to deploy

Not applicable

Hi,

I am trying to extract url in extract variable policy from soap request . Below is xpath :

<XPath>/soapenv:Envelope/soapenv:Header/sf:SessionHeader/sf:serverUrl/text()</XPath>

When I try to deploy the API , it throws below error .

Xpath is validated online. It returns url which am trying to extract.

Error Deploying

ExtractVariables Extract-Variables: Failed to compile xpath /soapenv:Envelope/soapenv:Header/sf:SessionHeader/sf:serverUrl/text(). Context Revision:1;APIProxy:hedgerxconnectservice;Organization:sp3rheldirrc1;Environment:test

Thanks,

Suma

Solved Solved
1 17 6,424
1 ACCEPTED SOLUTION

Hi, @Sumacv

For help with your specific case, can you please post the SOAP message and the full XPath policy configuration you are using (including the part where you specify the namespaces).

"Failed to compile xpath" suggests that you are using a namespace prefix in the XPath string that you have not previously "registered" with a Namespace declaration. Normally it would look something like this:

<ExtractVariables name='Extract-Response'>
  <VariablePrefix>result</VariablePrefix>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <XMLPayload>
    <Namespaces>
      <Namespace prefix='soap'>http://schemas.xmlsoap.org/soap/envelope/</Namespace>
      <Namespace prefix='ns1'>http://www.w3schools.com/xml/</Namespace>
    </Namespaces>
    <Variable name='fvalue' type='string'>
      <XPath>/soap:Envelope/soap:Body/ns1:CelsiusToFahrenheitResponse/ns1:CelsiusToFahrenheitResult/text()</XPath>
    </Variable>
    <Variable name='cvalue' type='string'>
      <XPath>/soap:Envelope/soap:Body/ns1:FahrenheitToCelsiusResponse/ns1:FahrenheitToCelsiusResult/text()</XPath>
    </Variable>
  </XMLPayload>
</ExtractVariables>
  

View solution in original post

17 REPLIES 17

With in extract Variable did you setup proper Namespaces for soapenv & sf?

Refer xml sample in http://docs.apigee.com/api-services/reference/extract-variables-policy

-Vinay

Hi, @Sumacv

For help with your specific case, can you please post the SOAP message and the full XPath policy configuration you are using (including the part where you specify the namespaces).

"Failed to compile xpath" suggests that you are using a namespace prefix in the XPath string that you have not previously "registered" with a Namespace declaration. Normally it would look something like this:

<ExtractVariables name='Extract-Response'>
  <VariablePrefix>result</VariablePrefix>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <XMLPayload>
    <Namespaces>
      <Namespace prefix='soap'>http://schemas.xmlsoap.org/soap/envelope/</Namespace>
      <Namespace prefix='ns1'>http://www.w3schools.com/xml/</Namespace>
    </Namespaces>
    <Variable name='fvalue' type='string'>
      <XPath>/soap:Envelope/soap:Body/ns1:CelsiusToFahrenheitResponse/ns1:CelsiusToFahrenheitResult/text()</XPath>
    </Variable>
    <Variable name='cvalue' type='string'>
      <XPath>/soap:Envelope/soap:Body/ns1:FahrenheitToCelsiusResponse/ns1:FahrenheitToCelsiusResult/text()</XPath>
    </Variable>
  </XMLPayload>
</ExtractVariables>
  

Hi,

Adding Namespace solved the Issue and was able to deploy . After this in Trace I could not see the extracted value from XMLPayload .

Same works when I convert to JSON and it works from JSON Payload

Thanks,

Suma

Hi Dino,

Below is the request content. Tring to extract sf:serverUrl and assigning it to a variable . This is not extracting .

Xpath : /soapenv:Envelope/soapenv:Header/sf:SessionHeader/sf:serverUrl/text()

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header>

<sf:SessionHeader>

<sf:sessionId></sf:sessionId>

<sf:serverUrl></sf:serverUrl>

</sf:SessionHeader>

</soapenv:Header>

<soapenv:Body> <ns1> <ns1> <ns1> <ns2> <ns2> <ns2> </ns1> </ns2> </soapenv:Body> </soapenv:Envelope>

Thanks,

Suma

Hi Sumacv,

The XML you posted is not well-formed. The sf namespace prefix is not defined there. Also there are other problems with unclosed elements (ns1 and ns2). Maybe you have posted a shortened version of the XML? or maybe the editor here has truncated it.

If you want to post code, can you please click the <code> button on the editor window, and insert your real code or XML there?

2165-click-to-add-code.png

@Floyd Jones - fyi, "failed to compile xpath" occurred here, at runtime, because the XPath used within ExtractVariables used a namespace prefix that was not defined in the <Namespaces> collection.

Thanks a ton for calling this out, @Dino! I've added some comments to the doc, including the error reference at the bottom of the topic.

Hello Dino,

Below is my xml

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <login xmlns="urn:xxxx.xxxx.xxxxx.com" xmlns:ns2="urn:fault.xxxx.xxxx.com">
      <credential>
        <companyId>company</companyId>
        <username>user</username>
        <password>password</password>
      </credential>
      <param>
        <name>batchSize</name>
        <value>200</value>
      </param>
    </login>
  </S:Body>
</S:Envelope>

I have used extract variable as below, hoewever i'm not getting the required element value, please help me to get the companyId element value

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="xmlpayloadextract">
    <DisplayName>comapnyxmlpayloadextract</DisplayName>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <Source clearPayload="false">request</Source>
    <XMLPayload stopPayloadProcessing="false">
      <Namespaces>
      <Namespace prefix="S">http://schemas.xmlsoap.org/soap/envelope/</Namespace>
      <Namespace prefix="ns1">urn:xxxx.xxxx.xxxx.com</Namespace>
      </Namespaces>
     <Variable name="companyid" type="string">
  <XPath>/S:Envelope/S:Body/ns1:login/ns1:credential/ns1:companyId/text()</XPath>
        </Variable>
    </XMLPayload>
</ExtractVariables>

Hi Venkat, I just tried this. It works for me. ??

Here is my policy:

<ExtractVariables name='Extract-1'>
  <Source>request</Source>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <XMLPayload>
    <Namespaces>
      <Namespace prefix='s'>http://schemas.xmlsoap.org/soap/envelope/</Namespace>
      <Namespace prefix='ns1'>urn:xxxx.xxxx.xxxxx.com</Namespace>
    </Namespaces>
    <Variable name='companyId' type='string'>
      <XPath>/s:Envelope/s:Body/ns1:login/ns1:credential/ns1:companyId/text()</XPath>
    </Variable>
  </XMLPayload>
</ExtractVariables>

I have that policy configured on the request flow, like this:

  <Flows>
    <Flow name='test1'>
      <Request>
        <Step><Name>Extract-1</Name></Step>
      </Request>
      <Response>
      </Response>
      <Condition>(proxy.pathsuffix MatchesPath "/t1") and (request.verb = "GET")</Condition>
    </Flow>
    ...

And I invoke it like this:

curl -i https://deecee-test.apigee.net/venkat1/t1 \
-H content-type:application/xml \
-d '<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <login xmlns="urn:xxxx.xxxx.xxxxx.com" xmlns:ns2="urn:fault.xxxx.xxxx.com">
      <credential>
        <companyId>company</companyId>
        <username>user</username>
        <password>password</password>
      </credential>
      <param>
        <name>batchSize</name>
        <value>200</value>
      </param>
    </login>
  </S:Body>
</S:Envelope>
'

And it works.

2174-it-works.png

Hello Dino,

Still it's not working for me. Please help me in resolving the issue.

Proxy:



<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="testextract">
    <DisplayName>testextract</DisplayName>
    
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    
    <Source clearPayload="false">request</Source>
    
    <XMLPayload stopPayloadProcessing="false">
        
      <Namespaces>
      <Namespace prefix='S'>http://schemas.xmlsoap.org/soap/envelope/</Namespace>
      <Namespace prefix='ns1'>urn:xxxx.xxxx.xxxx.com</Namespace>
    </Namespaces>
      
        <Variable name="name" type="string">
          <XPath>/S:Envelope/S:Body/ns1:login/ns1:credential/ns1:companyId/text()</XPath>
        </Variable>
    </XMLPayload>
</ExtractVariables>








Reuquest using postman:2182-postman-request.png

Trace:

2183-trace.png

Postman Request:

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header/>
<S:Body>
  <login xmlns="urn:xxxx.xxxx.xxxx.com" xmlns:ns2="urn:fault.xxxx.xxxx.com">
    <credential>
       <companyId>company</companyId>
       <username>user</username>
       <password>password</password>
    </credential>
  </login>
</S:Body>
</S:Envelope>

2187-postman-request.png

Trace:

2188-trace.png

Venkat, I believe you have a mismatch in the XML namespace. I have only one suggestion: look very closely and make sure the namespaces in your ExtractVariables policy correspond exactly to the namespaces in your XML payload. I've had this problem before with XPaths. You just have to look closely.

I think the namespace is not REALLY urn:xxxx.xxxx.xxxx.com , because that value changed between your prior post and this one. In one of your prior posts, that namespace had 5 x's in the last stanza, eg urn:xxxx.xxxx.xxxxx.com. And those are two different values. An XPath that works with a payload that uses one of those namespaces, will not work with a payload that uses the other. The namespace must match exactly.

Namespace issues can be very frustrating; I'm guessing that's what's got you here.

If you want to relax the namespace restriction (for ns1), you can use the much longer xpath like this:

<XPath>/S:Envelope/S:Body/*[local-name()='login']/*[local-name()='credential']/*[local-name()='companyId']/text()</XPath>

Not applicable

@Dino

Hi,

yes, here in post, im mentioning xxxx in the namespaces, however in my case, i'm copying the complete namespace.

check my findings.

I have two namespaces in login element

<login xmlns="urn:xxxx.xxxx.xxxx.com" xmlns:ns2="urn:fault.yyyy.yyyy.com">

when i declared namespace and xpath as follows





case:1


<Namespaces>
       <Namespace prefix='S'>http://schemas.xmlsoap.org/soap/envelope/</Namespace>
        <Namespace prefix='ns1'>urn:xxxx.xxxx.xxxx.com</Namespace>
    </Namespaces>
      
        <Variable name="companyid" type="string">
       <XPath>/S:Envelope/S:Body/ns1:login/ns1:credential/ns1:companyId/text()</XPath>



i'm getting error 




{
    "fault": {
        "faultstring": "IOException",
        "detail": {
            "errorcode": "Internal Server Error"
        }
    }
}



Case:2



<Namespaces>
       <Namespace prefix='S'>http://schemas.xmlsoap.org/soap/envelope/</Namespace>
        <Namespace prefix='ns2'>urn:yyyy.yyyy.yyyy.com</Namespace>
    </Namespaces>
      
        <Variable name="companyid" type="string">
          <XPath>/S:Envelope/S:Body/ns2:login/ns2:credential/ns2:companyId/text()</XPath>
        </Variable>




Result: No error, policy got executed successfully, however variable companyid is not getting resolved. I meant no value for it. it's having empty value




Case 3:


<Namespaces>
       <Namespace prefix='S'>http://schemas.xmlsoap.org/soap/envelope/</Namespace>
        
    </Namespaces>
      
        <Variable name="companyid" type="string">
          <XPath>/S:Envelope/S:Body/login/credential/companyId/text()</XPath>
        </Variable>


Result: No error, policy got executed successfully, however variable companyid is not getting resolved. I meant no value for it.it's having empty value




Case 4:

<Namespaces> 
<Namespace prefix='S'>http://schemas.xmlsoap.org/soap/envelope/</Namespace>
 </Namespaces> 
<Variable name="companyid" type="string">
 <XPath>/S:Envelope/S:Body/*[local-name()='login']/*[local-name()='credential']/*[local-name()='companyId']/text()</XPath> </Variable>





i'm getting error
{ "fault": { "faultstring": "IOException", "detail": { "errorcode": "Internal Server Error" } } }
 

Tired of different combinations, but still issue is there, I tried with variable type as "string" & node-set

Regards,

Ch.Venkat

@Dino : Please check it

Either case 1 or case 4 is correct. Case2 and 3 are both not going to work, because of namespaces.

I don't believe the IOException is occurring in the ExtractVariables policy. Check the trace for the API Proxy and verify where the error is occurring.

@Dino

yes,

we are able to see IO exception in case-1 and case-4

I have tried a strange thing in case-4 like below

<Namespaces>
       <Namespace prefix='S'>http://schemas.xmlsoap.org/soap/envelope/</Namespace>
        <Namespace prefix='ns2'>urn:fault.yyyy.yyyy.com</Namespace>
        
        
    </Namespaces>
      
        <Variable name="companyid" type="string">
          <XPath> /S:Envelope/S:Body/*[namespace-uri()='urn:sfobject.xxxx.xxxx.com' and local-name()='ns2:login']/*[namespace-uri()='urn:sfobject.xxxx.xxxx.com' and local-name()='ns2:credential']/*[namespace-uri()='urn:sfobject.xxxx.xxxx.com' and local-name()='ns2:companyId']/text()</XPath>
        </Variable>
    </XMLPayload>



Then IO exception is resolved, but receiving empty value for comapnyId.
I  believe now IO exception and reading the value (like /text() or variable type= string or node-set ) are the points, we need to consider.

Still im wondering how case-1 working in your case, where im getting IO exception. Could you let me know/check if any other global settings at apigee level is causing this IO exception issue

Regards,
Ch.Venkat

@Dino:

Issue is resolved. I'm sorry that i didn't mention about the proxy parameters. Have enabled request.streaming.enabled, payload is not getting read or updated during the proxy processing. After removing it, i'm able to read the value.

Both cases-1 and 4 are working. Thanks for your support 🙂

Regards,

Ch.Venkat.