Minnu
Minnu

Reputation: 21

Retrieving Xpath from SOAP Message

I want to retrieve all the xpaths from soap message at run time.

For example, if I have a soap message like

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Bodyxmlns:ns1="http://xmlns.oracle.com/TestAppln_jws/TestEmail/TestEmail">
 <ns1:process>
          <ns1:To></ns1:To>
          <ns1:Subject></ns1:Subject>
          <ns1:Body></ns1:Body>
        </ns1:process>
    </soap:Body>
</soap:Envelope>

then the possible xpaths from this soap message are

  1. /soap:Envelope/soap:Body/ns1:process/ns1:To
  2. /soap:Envelope/soap:Body/ns1:process/ns1:Subject
  3. /soap:Envelope/soap:Body/ns1:process/ns1:Body

How can i retrive those with java?

Upvotes: 2

Views: 4153

Answers (2)

McDowell
McDowell

Reputation: 108859

Use the XPath type with a NamespaceContext.

Map<String, String> map = new HashMap<String, String>();
map.put("foo", "http://xmlns.oracle.com/TestAppln_jws/TestEmail/TestEmail");
NamespaceContext context = ...; //TODO: context from map
XPath xpath = ...; //TODO: create instance from factory
xpath.setNamespaceContext(context);

Document doc = ...; //TODO: parse XML
String toValue = xpath.evaluate("//foo:To", doc);

The double forward slash makes this expression match the first To element in the http://xmlns.oracle.com/TestAppln_jws/TestEmail/TestEmail in the given node. It does not matter that I used foo instead of ns1; the prefix mapping needs to match the one in the XPath expression, not the one in the document.

You can find further examples in Java: using XPath with namespaces and implementing NamespaceContext. You can find further examples of working with SOAP here.

Upvotes: 2

Andy Hunt
Andy Hunt

Reputation: 1073

Something like this could work:

string[] paths;
function RecurseThroughRequest(string request, string[] paths, string currentPath)
{
    Nodes[] nodes = getNodesAtPath(request, currentPath); 
    //getNodesAtPath is an assumed function which returns a set of 
    //Node objects representing all the nodes that are children at the current path

    foreach(Node n in nodes)
    {
        if(!n.hasChildren())
        {
            paths.Add(currentPath + "/" + n.Name);
        }
        else
        {
            RecurseThroughRequest(paths, currentPath + "/" + n.Name);
        }

    }
}

And then call the function with something like this:

string[] paths = new string[];
RecurseThroughRequest(request, paths, "/");

Of course that won't work out of the gates, but I think the theory is there.

Upvotes: 0

Related Questions