Question

I'm trying to develop a SOAP client & parser which is specific to our project. I've already finished the client and it invokes many kinds of (several different) SOAP web services and getting response SOAP message in XML format.

My goal:

Get the value of any node or attribute from any type of collection and it should be worked for all of my web services responses.

e.g. I will call like as this:

String h1 = collection.get("html/body/h1");

and h1's value should be 'StackOverflow' and come from:

<html>
  <head></head>
  <body>
    <h1>StackOverflow</h1>
    <p>XML parsing in Java</p>
  </body>
</html>

etc.

My approach:

Now i have the response message. I want to parse it and assign all the node (and attribute) values to a collection (map) and get data from that collection. The collection's (Map ) key would be the path of node and the value would be the node's or attribute's value.

e.g

<MethodResponse xmlns="any.xmlns">
    <MethodResult>any value</MethodResult>
    <Node1>
        <Node2>
            <Node3>
                node3 value is here
            <Node3>
        </Node2>
    </Node1>
    <respCode>99</respCode>
    <respNote>any value</respNote>
</MethodResponse>

If i need to respCode in here, i would be able to call that in this way:

String respCode = map.get("/MethodResponse/respCode");

or, to Node3:

String node3Value = map.get("/MethodResponse/Node1/Node2/Node3");

like as XPath. But i don't want to any mapping or any Java class. I just want to access nodes (or attributes) value from its path.

Success criteria:

It works for these and several different SOAP messages:

And my questions:

  1. Is my approach true?
  2. If yes, how can i do that? Is there any working code or tutorial?
  3. If no, how can i do that?
Was it helpful?

Solution

Creating a Java DOM XML parser is done using the javax.xml.parsers.DocumentBuilderFactory class. Here is an example:

DocumentBuilderFactory builderFactory =
        DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
    builder = builderFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
    e.printStackTrace();  
}

Parsing an XML file into a DOM tree using the DocumentBuilder is done like this:

try {
    Document document = builder.parse(
            new FileInputStream("data\\text.xml"));
} catch (SAXException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

At the top is the Document object. The Document object has a single root element, which is returned by calling getDocumentElement() like this:

Element rootElement = document.getDocumentElement();

get the children of an element

NodeList nodes = element.getChildNodes();

for(int i=0; i<nodes.getLength(); i++){
  Node node = nodes.item(i);

  if(node instanceof Element){
    //a child element to process
    Element child = (Element) node;
    String attribute = child.getAttribute("width");
  }
}

Now you have a needed Node, so you can create put it in map as you wish, and make need for you key. method transformer.transform(new DOMSource(document),work with any Dom node or element

Create String from Document

TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
StringWriter buffer = new StringWriter();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new DOMSource(document),
      new StreamResult(buffer));
String str = buffer.toString();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top