Question

I need to parse a SOAP response in perl:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header xmlns:iden="http://identifycaller.customermanagement.schema.amx.com"/>
   <soapenv:Body xmlns:iden="http://identifycaller.customermanagement.schema.amx.com">
      <ns2:Fault xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>ns2:server</faultcode>
         <faultstring>Error interno del servicio. Por favor contacte al administrador.    </faultstring>
         <detail>
            <ns2:InternalSystemErrorException xmlns:ns2="http://commonsexceptions.schema.amx.com">
               <ns2:errorCode>1049581</ns2:errorCode>
               <ns2:errorMsg>Error tecnico</ns2:errorMsg>
               <ns2:message>Error interno del servicio. Por favor contacte al administrador.</ns2:message>
            </ns2:InternalSystemErrorException>
         </detail>
      </ns2:Fault>
   </soapenv:Body>
</soapenv:Envelope>

My code:

my $xml = $response->content;
my $dom = XML::LibXML->load_xml( string => (\$xml) );        

my $xpc = XML::LibXML::XPathContext->new($dom);
$xpc->registerNs('ns2', 'http://commonsexceptions.schema.amx.com');

my $errorCode = $xpc->findvalue('/*/ns2:errorCode');
my $errorMessage = $xpc->findvalue('/*/ns2:message');

print "Codigo $errorCode: $errorMessage\n";

I am unable to get the correct XPATH expression to get ns2:errorCode and ns2:message. I've read lots of answers and will continue playing with this but time is getting short.

I'm using perl 5.16 under windows but plan to deploy on perl 5.8.4 under solaris. I'm also using XML::LibXML.

Was it helpful?

Solution

I'm glad that removing the '*' from the XPath statement worked. I believe I can provide a more detailed explanation. Your original XPath statement was looking for ns2:errorCode and ns2:message one level underneath the root node. By removing the asterisk from the XPath and using // shortcut to begin the search you're actually searching the entire document for any elements name ns2:errorCode and ns2:message.

One side note, this is actually less efficient as the parser has to go through all elements. A more efficient XPath statement is /soapenv:Envelope/soapenv:Body/ns2:Fault/detail/ns2:InternalSystemErrorException/ns2:errorCode and ns2:message. By specifying the full path you're telling the parser exactly where to look for your nodes. Take a look at point #9 on this page.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top