views:

200

answers:

1

I have to write a generic template for finding an operation name and the namespace for that from a soap response. Generic i mean, that is applicable to any operation. So I don't know the operation name and the name space name but want to get them and modify back when I am sending the response.

Here is the structure of the response:

Type 1: namespace for operation is defined in <soapenv:Envelope>:

<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:inf="http://bad.com/abc/infrastructure" 
  xmlns:ret="http://bad.com/FirstOperationToExecute" 
  xmlns:com="http://bad.com/commercial"&gt;
  <soapenv:Header/>
  <soapenv:Body>
    <ret:retrieveSummaryRequest>
      <!-- ... result ... -->
    </ret:retrieveSummaryRequest>
  </soapenv:Body>
</soapenv:Envelope>

Type 2: namespace defined in the element <ret:retrieveSummaryRequest>:

<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:inf="http://bad.com/abc/infrastructure" 
  xmlns:ret="http://bad.com/FirstOperationToExecute" 
  xmlns:com="http://bad.com/commercial"&gt;
  <soapenv:Header/>
  <soapenv:Body>
    <ret:retrieveSummaryRequest xmlns:ret="http://bad.com/FirstOperationToExecute" > 
      <!-- ... result ... -->
    </ret:retrieveSummaryRequest>
  </soapenv:Body>
</soapenv:Envelope>

Type 3: default namespace in <retrieveSummaryRequest>:

<soapenv:Envelope 
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
  xmlns:inf="http://bad.com/abc/infrastructure" 
  xmlns:ret="http://bad.com/FirstOperationToExecute" 
  xmlns:com="http://bad.com/commercial"&gt;
  <soapenv:Header/>
  <soapenv:Body>
    <retrieveSummaryRequest xmlns="http://bad.com/FirstOperationToExecute" > 
      <!-- ... result ... -->
    </retrieveSummaryRequest>
  </soapenv:Body>
</soapenv:Envelope>

Can somebody help me telling if there is a simple XPath statement for this to get the operation name and namespace.

A: 

All of the above XML samples represent equivalent infosets. They are equal, all things considered. The differences affect the serialized (text) form only, so they should not bother you.

If I understand you right, you want to retrieve these two values:

  • "http://bad.com/FirstOperationToExecute"
  • "FirstOperationToExecute"

To get hold of these values in XSLT, use:

<xsl:template match="ret:retrieveSummaryRequest">
  <!-- the full URI -->
  <xsl:value-of select="namespace-uri()" />

  <!-- the operation name only -->
  <xsl:value-of select="
    substring-after(
      substring-after(namespace-uri(), '//'), 
      '/'
    )
  " />
</xsl:template>

If you are not in XSLT, then retrieving the operation name is a matter of selecting the right node and asking the DOM for the namespace URI. Pseudo-code:

dom.registerNSPrefix("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
ret    = dom.selectSingleNode("/soapenv:Envelope/soapenv:Body/*[1]");
nsUri  = ret.namespaceURI;
opName = nsUri.replace(".*/", ""); // whatever
Tomalak