Parsing CDATA content from webservice response in Java - java

I'm making a webservice call in my Java code and getting the response as String with the below data.
<DocumentElement>
<ResultSet>
<Response>Successfully Sent.</Response>
<UsedCredits>1</UsedCredits>
</ResultSet>
</DocumentElement>
Now, I want to parse the below response String and get the value of <Response> tag alone for further processing. Since, I'm getting only the CDATA content how to parse the String content?

You obviously need XML parser for this one. Lets say the above is stored in a String variable named content
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
//Using factory get an instance of document builder
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(content)); //content variable holding xml records
Document doc = db.parse(is)
/* Now retrieve data from xml */
NodeList nodes = doc.getElementsByTagName("ResultSet");
Element elm = (Element) nodes.item(0); //will get you <Response> Successfully Sent.</Response>
String responseText = elm.getFirstChild().getNodeValue();
}catch(ParserConfigurationException pce) {
pce.printStackTrace();
}catch(SAXException se) {
se.printStackTrace();
}catch(IOException ioe) {
ioe.printStackTrace();
}
Follow the above parser routine for larger data sets. Use loops for multiple similar data sets. Hope that helps.

Related

How to parse SOAP response using Java API

I'm executing the SOAP web services using Karate API and its generating SOAP-based response.
Then I write the response into an XML file using Java Code - File has been created successfully.
Here's the sample SOAP Response Content which I have...
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getMbrWksMembershipDetailsResponse xmlns:ns1="http://www.xxxxxxx.com/services/customersummary">
<ns4:WksMembershipSummaryResponse xmlns:ns2="http://www.xxxxxxx.com/services/customersummary/contract" xmlns:ns3="http://www.xxxxx.com/eom" xmlns:ns4="http://www.xxxx.com/services/customersummary">
<ns2:customerSummary>
<ns2:address>
<ns2:city>SOUTH CHESTERFIELD</ns2:city>
<ns2:country>USA</ns2:country>
<ns2:isoCountryCode>US</ns2:isoCountryCode>
<ns2:line1>9998, N. MICHIGAN ROAD.</ns2:line1>
<ns2:postalCode>23834</ns2:postalCode>
<ns2:state>VA</ns2:state>
</ns2:address>
<ns2:allowPasswordChange>true</ns2:allowPasswordChange>
<ns2:arpMember>false</ns2:arpMember>
<ns2:brandCode>RCI</ns2:brandCode>
<ns2:brandId>1</ns2:brandId>
<ns2:companyCode>RCI</ns2:companyCode>
..........
I have written a java code for fetching the tag value e.g. firstName. This is Java method.
public static String getTagValue(String strResponseFile, String strTagName)
{
String fileLoc = "D:\\getMembershipDetailsResponse.xml";
try
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false);
DocumentBuilder db = dbf.newDocumentBuilder();
**Document doc = db.parse(new InputSource(new FileReader(fileLoc)));**
XPath xpath = XPathFactory.newInstance().newXPath();
Node n1 = (Node)xpath.evaluate("//customerSummary/brandCode", doc.getDocumentElement(), XPathConstants.NODE);
System.out.println(n1.getNodeValue());
Node c1 = (Node)xpath.evaluate("//customerSummary/firstName",doc.getDocumentElement(), XPathConstants.NODE);
System.out.println(c1.getNodeValue());
}
catch(Exception e)
{
}
return "";
}
I'm getting NULL in the above bold line of Java code. Can you please give your valuable suggestion on that to resolve the issue?
Thanks,

Converting XML to document in java creates null document

I'm trying to parse xml, downloaded from the web, in java, following examples from here (stackoverflow) and other sources.
First I pack the xml in a string:
String xml = getXML(url, logger);
If I printout the xml string at this point:
System.out.println("XML " + xml);
I get a printout of the xml so I'm assuming there is no fault up to this point.
Then I try to create a document that I can evaluate:
InputSource is= new InputSource(new StringReader(xml));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(is);
If I print out the document here:
System.out.println("Doc: " + doc);
I get:
Doc: [#document: null]
When I later try to evaluate expressions with Xpath I get java.lang.NullPointerException and also when just trying to get the length of the root:
System.out.println("Root length " + rootNode.getLength());
which leaves me to believe the document (and later the node) is truly null.
When I try to print out the Input Source or the Node I get eg.
Input Source: org.xml.sax.InputSource#29453f44
which I don't know how to interpret.
Can any one see what I've done wrong or suggest a way forward?
Thanks in advance.
You may need another way to render the document as a string.
For JDOM:
public static String toString(final Document document) {
try {
final ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
final XMLOutputter outp = new XMLOutputter();
outp.output(document, out);
final String string = out.toString("UTF-8");
return string;
}
catch (final Exception e) {
throw new IllegalStateException("Cannot stringify document.", e);
}
}
The output
org.xml.sax.InputSource#29453f44
simply is the class name + the hash code of the instance (as defined in the Object class). It indicates that the class of the instance has toString not overridden.

Parsing a SOAP response is returning null

String response = "<?xml version='1.0'?><soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope'><soap:Body><exch:Response xmlns:exch='http://applicant.ffe.org/exchange/1.0'>...</exch:Response></soap:Body></soap:Envelope>";
DocumentBuilderFactory dbf = null;
DocumentBuilder db = null;
org.w3c.dom.Document document = null;
try {
dbf = DocumentBuilderFactory.newInstance();
db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new ByteArrayInputStream(response.getBytes("UTF-8")));
document = db.parse(is);
} catch(ParserConfigurationException e){}
catch(SAXException e){}
document is returning with null. I have tried different ways to pass to InputSource, but document is still returning null. Any idea why this might be happening?
I just tried i could get the elements name and values .
try {
dbf = DocumentBuilderFactory.newInstance();
db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new ByteArrayInputStream(response.getBytes("UTF-8")));
document = db.parse(is);
System.out.println(document);//here we get null;
System.out.println(document.getNodeName());//here we get document;
for(int i =0 ; i<document.getChildNodes().getLength();i++)
System.out.println(document.getChildNodes().item(i).getChildNodes().item(i).getNodeName());
}
Output :
[#document: null]
document
soap:Body
To parse SOAPResponse we can javax.xml.soap.* it may take u to traverse the object xml tree. Anyway we may need parse the elements from SOAP Body . we could parse these very simple manner using DOM format .

Java Web Service returns string with > and < instead of > and <

I have a java web service that returns a string. I'm creating the body of this xml string with a DocumentBuilder and Document class. When I view source of the returned XML (Which looks fine in the browser window) instead of <> it's returning < and > around the XML nodes.
Please help.
****UPDATE (including code example)
The code is not including any error catching, it was stripped for simplicity.
One code block and three methods are included:
The first code block (EXAMPLE SETUP) shows the basics of what the Document object is setup to be like. the method appendPayment(...) is where the actual document building happens. It calls on two helper methods getTagValue(...) and prepareElement(...)
**Note, this code is meant to copy specific parts from a pre-existing xml string, xmlString, and grap the necessary information to be returned later.
****UPDATE 2
Response added at the end of the question
************ Follow-up question to the first answer is here:
How to return arbitrary XML Document using an Eclipse/AXIS2 POJO Service
EXAMPLE SETUP
{
//create new document
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder newDocBuilder = docFactory.newDocumentBuilder();
Document newDoc = newDocBuilder.newDocument();
Element rootElement = newDoc.createElement("AllTransactions");
newDoc.appendChild(rootElement);
appendPayment(stringXML, newDoc);
}
public static void appendPayment(String xmlString, Document newDoc) throws Exception
{
//convert string to inputstream
ByteArrayInputStream bais = new ByteArrayInputStream(xmlString.getBytes());
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document oldDoc = docBuilder.parse(bais);
oldDoc.getDocumentElement().normalize();
NodeList nList = oldDoc.getChildNodes();
Node nNode = nList.item(0);
Element eElement = (Element) nNode;
//Create new child node for this payment
Element transaction = newDoc.createElement("Transaction");
newDoc.getDocumentElement().appendChild(transaction);
//status
transaction.appendChild(prepareElement("status", eElement, newDoc));
//amount
transaction.appendChild(prepareElement("amount", eElement, newDoc));
}
private static String getTagValue(String sTag, Element eElement)
{
NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = (Node) nlList.item(0);
return nValue.getNodeValue();
}
private static Element prepareElement(String sTag, Element eElement, Document newDoc)
{
String str = getTagValue(sTag, eElement);
Element newElement = newDoc.createElement(sTag);
newElement.appendChild(newDoc.createTextNode(str));
return newElement;
}
Finally, I use the following method to convert the final Document object to a String
public static String getStringFromDocument(Document doc)
{
try
{
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
return writer.toString();
}
catch(TransformerException ex)
{
ex.printStackTrace();
return null;
}
}
The header type of the response is as follows
Server: Apache-Coyote/1.1
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
This is an example response
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<getTransactionsResponse xmlns="http://services.paypal.com">
<getTransactionsReturn><AllTransactions><Transaction><status>PENDING</status><amount>55.55</amount></transaction>
</getTransactionsResponse>
</soapenv:Body>
</soapenv:Envelope>
The framework is doing what you tell it; your method returns a String which means the generated WSDL should have a response message of type <xsd:string>. As we know, XML strings must encode certain characters as character entity references (i.e. "<" becomes "<" so the XML parser treats it as a string, not the beginning of an XML element as you intend). If you want to return an XML document then you must define the XML structure in the WSDL <types> section and set the response message part to the appropriate element.
To put it another way, you are trying to send "typed" data without using the strong type system provided by SOAP/WSDL (namely XML schema); this is generally regarded as bad design (see Loosely typed versus strongly typed web services).
The ultimate solution is to to define the response document via a proper XML Schema. If there is no set schema, as by the design of your service, then use the <xsd:any> type for the message response type, although this approach has its pitfalls. Moreover, such a redesign implies a schema-first (top-down) development model and from the comment stream it seems that you are currently practicing code-first (bottom-up) approach. Perhaps your tools provide a mechanism such as a "general XML document" return type or annotation which achieves the same effect.

How to create a XML object from String in Java?

I am trying to write a code that helps me to create a XML object. For example, I will give a string as input to a function and it will return me a XMLObject.
XMLObject convertToXML(String s) {}
When I was searching on the net, generally I saw examples about creating XML documents. So all the things I saw about creating an XML and write on to a file and create the file. But I have done something like that:
Document document = new Document();
Element child = new Element("snmp");
child.addContent(new Element("snmpType").setText("snmpget"));
child.addContent(new Element("IpAdress").setText("127.0.0.1"));
child.addContent(new Element("OID").setText("1.3.6.1.2.1.1.3.0"));
document.setContent(child);
Do you think it is enough to create an XML object? and also can you please help me how to get data from XML? For example, how can I get the IpAdressfrom that XML?
Thank you all a lot
EDIT 1: Actually now I thought that maybe it would be much easier for me to have a file like base.xml, I will write all basic things into that for example:
<snmp>
<snmpType><snmpType>
<OID></OID>
</snmp>
and then use this file to create a XML object. What do you think about that?
If you can create a string xml you can easily transform it to the xml document object e.g. -
String xmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><a><b></b><c></c></a>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xmlString)));
} catch (Exception e) {
e.printStackTrace();
}
You can use the document object and xml parsing libraries or xpath to get back the ip address.
try something like
public static Document loadXML(String xml) throws Exception
{
DocumentBuilderFactory fctr = DocumentBuilderFactory.newInstance();
DocumentBuilder bldr = fctr.newDocumentBuilder();
InputSource insrc = new InputSource(new StringReader(xml));
return bldr.parse(insrc);
}

Categories

Resources