ATS : REST Operations - Parsing XML body

Introduction

XML (Extensible Markup Language) is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable similar to JSON and YAML.

In this page we will use mostly the following example:

<person id="121213266">
	<firstname>Indianna</firstname>
	<lastname>Jones</lastname>
	<age>10</age>
</person>

 


Different ways to specify the XML body

Java object:

Person xmlBody = new Person();
xmlBody.setFirstName( "Indiana" );
xmlBody.setLastName( "Johnes" );
xmlBody.setAge( 40 );

This is the easiest to use way, but sometimes the problem is that you do not have the jar with the needed class(in this example this is the Person class).

Simple text:

String xmlBody = "<person id=\"121213266\"><firstname>Indiana</firstname><lastname>Jones</lastname><age>10</age></person>";

The formatting here is not always understandable. Additionally it will be very difficult to extract a value from such (String) response.

XML text:

import com.axway.ats.action.xml.XmlText;

XmlText xmlBody = new XmlText("<person/>");
xmlBody.setAttribute("//person","id","121213266");
xmlBody.add("//person","<firstname>Indiana</firstname>");
xmlBody.add("//person","<lastname>Jones</lastname>");
xmlBody.add("//person","<age>10</age>"); 

In this example we are using our XmlText class provided by ATS. You still do not need the corresponding java class, but the working with this class is much easier compared to regular String.

All presented 3 examples above send the request in the same way:

RESTResponse response = client.postObject( xmlBody );

 


Constructing XMLText

Fetched as body of a response

XmlText xmlBody = client.get().getBodyAsXml();

Provide text content when constructing the instance

XmlText xmlBody = new XmlText("<person id=\"121213266\"><firstname>Indiana</firstname><lastname>Jones</lastname><age>10</age></person>"; );

Add items one by one

XmlText xmlBody = new XmlText("<person/>");
xmlBody.setAttribute("//person","id","121213266");
xmlBody.add("//person","<firstname>Indiana</firstname>");
xmlBody.add("//person","<lastname>Jones</lastname>");
xmlBody.add("//person","<age>10</age>"); 

Constructing complex content

Imagine you need to construct a more complex example like the following:

<department total-people="10">
	<person id="121213266">
		<firstname>Indianna</firstname>
		<lastname>Jones</lastname>
		<age>10</age>
	</person>
	<person id="101015033">
		<firstname>Will</firstname>
		<lastname>Smith</lastname>
		<age>20</age>
	</person>
</department> 

Here is how you can do it:

new XmlText("<department/>")
	.setAttribute("/","total-people","10")
	.add("/", new XmlText("<person/>")
			          .setAttribute("/","id","121213266")
			          .add("/", new XmlText("<firstname/>").setText("/","Indiana") )
     			      .add("/", new XmlText("<lastname/>").setText("/","Jones") )
		     	      .add("/", new XmlText("<age/>").setText("/","10") )
	)
	.add("/", new XmlText("<person/>")
			          .setAttribute("/","id","101015033")
                      .add("/", new XmlText("<firstname/>").setText("/","Will") )
            		  .add("/", new XmlText("<lastname/>").setText("/","Smith") )
			          .add("/", new XmlText("<age/>") .setText("/","20") 	)
	);

Many XmlText methods return the result instance, so if you want, you can chain as in the example:

XmlText xmlBody = new XmlText("<person id='121213266'/>").add("/","<firstname>Indiana</firstname>").add("/","<lastname>Jones</lastname>").add("/","<age>10</age>");

of course you can always use the other option:

XmlText xmlBody = new XmlText("<person/>");
xmlBody.setAttribute("/","id","121213266");
xmlBody.add("/","<firstname>Indiana</firstname>");
xmlBody.add("/","<lastname>Jones</lastname>");
xmlBody.add("/","<age>10</age>");

In some examples , we are using " /" for XPath , which points to the root element of the XML document.

There are two ways to point to an XML element via XPath - absolute and relative.

The absolute XPath is constructed from the root element of the XML document , down to the element , you are looking for.

Example : "/department/person[2]/age" or "/department/person[@id='101015033']/age"

The relative XPath is constructed from any XML element , which XPath is unique for the XML document , instead of from the root element of the document.

Example : "//person[2]/age" or "//person[@id='101015033']/age"


Note that absolute XPath , starts with single slash while relative XPath starts with double slash.

The above java code may look complex, but the actual output is complex too.

Using this approach is good when you are taking some programmatic approach in constructing your XML body. For example if the input comes from some template file or some user interaction - then you can use this approach to add the needed content.

 


Retrieving content from XmlText

Here is how you can get some XML value:

XMLText xmlBody = client.get().getBodyAsXml();

// get a String value
String firstName = xmlBody.getString( "//person[@id='121213266']/firstname");

// get an int value
int age = xmlBody.getInt( "/department/person[1]/age");

 


Modifying content

You can replace some values in the XML text:

// by replacing XML element
xmlBody.replace( "/department/person[1]/firstname", "<firstname>Will</firstname>" );

// by changing the text of XML element
xmlBody.setText( "/department/person[1]/age", "35" );

Or you can delete some of the content:

// here we are using the absolute XPath , pointing to XML element <firstname/>
xmlBody.remove( "/department/person[1]/firstname" );

// here we are using the relative XPath , pointing to XML element <age/>
xmlBody.remove( "//person[@id='121213266']/firstname/age" );

 


Pointing deeper in the content

We are using some simple expression language to point to the right key somewhere inside. Here are some examples:

// this will return 10
xmlBody.getAttribute("/department","total-people")

// this will return "Indiana"
xmlBody.getString( "/department/people[1]/firstname" );

All methods use same approach to point to a key of interest - getString, replace or remove

 


Modifying XML attributes

You can see all attributes for a certain XML element:

Map<String, String> attributes = xmlBody.getAttributes("/department/person[1]");

Or you can see certain attribute value, change attribute's value , or remove the attribute:

// get an attribute , this will return 101015033
String id = xmlBody.getAttribute("/department/person[2]","id");

// set new attribute
xmlBody.setAttribute("//department","country","Bulgaria");

// change the content of an attribute
xmlBody.setAttribute("//department","total-people","30");

// remove an attribute
xmlBody.removeAttribute("//department","country");

 


Nicely formatting the XML text

You have the option to print the XML text as regular or as a well formatted text.

For example using the toString() method may give you output like the following:

<department total-people="10"><person id="121213266"><firstname>Indiana</firstname><lastname>Jones</lastname><age>10</age></person><person id="101015033"><firstname>Will</firstname><lastname>Smith</lastname><age>20</age></person></department>

while using the toFormattedString() method for the same XML text will give you output like the following:

<department total-people="10">
	<person id="121213266">
		<firstname>Indiana</firstname>
		<lastname>Jones</lastname>
    	<age>10</age>
  	</person>
  	<person id="101015033">
    	<firstname>Will</firstname>
    	<lastname>Smith</lastname>
    	<age>20</age>
  	</person>
</department>

 


Iterating over the XML text content

If you do not know the content, but want to explore it, you can use the following example as a starting point.

for( String xpath : xmlBody.getElementXPaths() ) {
     // here we get the XPath of the next element

     // do something with the found element, in this case we just print it out
     System.out.println( xpath + " : " + xmlBody.getString( xpath ) );

     // or we can navigate to it
     XMLText xmlText = xmlBody.get( xpath );
}			 

 


Back to parent page

Go to Table of Contents