Java parse XML string - java

I have an string which I am attempting to extract values from, for convenience I thought that converting the string to a Document and then parsing the xml would be the best way to do this but I am running into all sorts of problems! The string looks like:
<Messagexxx>
<Unit>
<contact>0</contact>
<text>Test Content</text>
<date>09-Sep-14 13:56</date>
<subject>Test Title</subject>
</Unit>
</Messagexxx>
Can someone point me in the correct way to achieve my goal of reading the values from the tags .
I have attempted using the following snippet but I all the values in the array are
null! Document xml = null; Node T = null; try { xml = stringToDom(message); T = xml.getLastChild(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(xml.getFirstChild() != null){ }

When you write your string to a text file, you can first parse it:
private Document parse(String filename){
Document doc = null;
try {
DOMParser parser = new DOMParser();
parser.parse(filename);
doc = parser.getDocument();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return doc;
}
and then you read all text elements out of this document:
public void extract (Document doc){
Node root = doc.getDocumentElement();
for (int i = 0; i< root .getChildNodes().getLength(); i++){
Node child = root.getChildNodes().item(i);
System.out.println(child.getTextContent());
}
}

Use JAXB lib : https://jaxb.java.net/
Create your model from your XML and to read :
JAXBContext jaxbContext = JAXBContext.newInstance(YourModel.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader("xml string here");
YourModel yourModel= (Person) unmarshaller.unmarshal(reader);
After your can use the object "YourModel" to read your value.

This is a very simple way to get node values when you know the node names, and they don't repeat:
String getXmlNodeValue(String xmlString, String nodeName){
int start = xmlString.indexOf("<"+nodeName+">") + nodeName.length() + 2;
int end = xmlString.indexOf("</"+nodeName+">");
return xmlString.substring(start, end);
}

Related

Convert an XML String to CSV file (Java) -> CSV Result is empty

I need help understanding why the XML String does not convert into a CSV file. Why is the CSV Resut always empty?
Here is an example of a Java Code
public class transformCSV_1 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
String xmlData = new String(
"<?xml version=\"1.0\"?><PurchaseOrder xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd\"><Reference>SBELL-2002100912333601PDT</Reference><Actions><Action><User>SVOLLMAN</User></Action></Actions><Requestor>Sarah J. Bell</Requestor><User>SBELL</User><CostCenter>S30</CostCenter><ShippingInstructions><name>Sarah J. Bell</name><address>400 Oracle Parkway Redwood Shores CA 94065 USA</address><telephone>650 506 7400</telephone></ShippingInstructions><SpecialInstructions>Air Mail</SpecialInstructions><LineItems><LineItem ItemNumber=\"1\"><Description>A Night to Remember</Description><Part Id=\"715515009058\" UnitPrice=\"39.95\" Quantity=\"2\"/></LineItem><LineItem ItemNumber=\"2\"><Description>The Unbearable Lightness Of Being</Description><Part Id=\"37429140222\" UnitPrice=\"29.95\" Quantity=\"2\"/></LineItem><LineItem ItemNumber=\"3\"><Description>Sisters</Description><Part Id=\"715515011020\" UnitPrice=\"29.95\" Quantity=\"4\"/></LineItem></LineItems></PurchaseOrder>");
String stylesheet = new String(
"<?xml version=\"1.0\" encoding=\"utf-8\"?><xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:output method=\"text\" /><xsl:variable name=\"delimiter\" select=\"','\" /><!-- define an array containing the fields we are interested in --><xsl:variable name=\"fieldArray\"><field>Reference</field><field>User</field><field>Reject</field><field>Requestor</field></xsl:variable><xsl:param name=\"fields\" select=\"document('')/*/xsl:variable[#name='fieldArray']/*\" /><xsl:template match=\"/\"><!-- output the header row --><xsl:for-each select=\"$fields\"><xsl:if test=\"position() != 1\"><xsl:value-of select=\"$delimiter\"/></xsl:if><xsl:value-of select=\".\" /></xsl:for-each><!-- output newline --><xsl:text>
</xsl:text><xsl:apply-templates select=\"PurchaseOrder\"/></xsl:template><xsl:template match=\"PurchaseOrder\"><xsl:variable name=\"currNode\" select=\".\" /><!-- output the data row --><!-- loop over the field names and find the value of each one in the xml --><xsl:for-each select=\"$fields\"><xsl:if test=\"position() != 1\"><xsl:value-of select=\"$delimiter\"/></xsl:if><xsl:value-of select=\"$currNode/*[name() = current()]\" /></xsl:for-each><!-- output newline --><xsl:text>
</xsl:text></xsl:template></xsl:stylesheet>");
InputStream xmlSource = new ByteArrayInputStream(
xmlData.getBytes("UTF-8"));
InputStream styleSource = new ByteArrayInputStream(
stylesheet.getBytes("UTF-8"));
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlSource);
StreamSource stylesource = new StreamSource(styleSource);
Transformer transformer = TransformerFactory.newInstance()
.newTransformer(stylesource);
Source source = new DOMSource(document);
Result outputTarget = new StreamResult(new File("src/resultI.csv"));
transformer.transform(source, outputTarget);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Best way is to use XSLT to "transform" the XML to CSV --> Can someone give me hint?
Consider to load the XSLT code from a file or URI (instead of from a string) as otherwise your approach of doing <xsl:param name="fields" select="document('')/*/xsl:variable[#name='fieldArray']/*" /> where document('') tries to pull in the XSLT code again is likely to fail, unless you set up a special resolver.

How can I put the value from an XML file into an array list in another class in java?

I am reading in an XML file, and trying to return the values in another class using Java. In the XML Reader I read in the values from the XML file. I'm not quite sure how to do this. Any help would be appreciated.
public class XMLReader {
public static List<String> load()
{
try{
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse (new File("C:/adapters.xml"));
doc.normalize();
NodeList rootNodes = doc.getElementsByTagName("adapters");
Node rootNode = rootNodes.item(0);
Element rootElement = (Element) rootNode;
NodeList adaptersList = rootElement.getElementsByTagName("class");
for(int i=0; i<adaptersList.getLength(); i++){
Node theAdapter = adaptersList.item(i);
Element adpElement = (Element) theAdapter;
System.out.println("This is: " + adpElement.getTextContent());
}
}catch(ParserConfigurationException e){
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public class AdapterLoader {
public static List<AbstractAdapter> loadAllAdapters()
{
List<AbstractAdapter> allAdapters = new ArrayList<AbstractAdapter>();
List<String> adapterClasses = XMLReader.load();
for (String className : adapterClasses)
{
try {
Class adapters = Class.forName(className);
AbstractAdapter adp = (AbstractAdapter) adapters.newInstance();
allAdapters.add(adp);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return allAdapters;
}
}
Instead of printing it to console
System.out.println("This is: " + adpElement.getTextContent());
add this to a List and return that instead of
return null;

How to get values and keys through single line string xml in android [duplicate]

This question already has answers here:
How do I parse JSON in Android? [duplicate]
(3 answers)
Closed 8 years ago.
I am encounter a problem. I have following xml
<string>[{"BatchIDs":[],"HomeWorkCategoryName":"","FileURL":"","FileName":"","ID":1,"Title":"test","Description":"test","HomeworkCategoryID":1,"ExpiryDate":"\/Date(1386658800000)\/","FileID":-2147483648,"URL":"","Mode":1,"Type":2,"Status":1,"CreatedOnDate":"\/Date(1388093500883)\/","UpdatedOnDate":"\/Date(1388093500883)\/","Inactive":false,"Deleted":true},
{"BatchIDs":[],"HomeWorkCategoryName":"","FileURL":"","FileName":"","ID":1,"Title":"test","Description":"test","HomeworkCategoryID":1,"ExpiryDate":"\/Date(1386658800000)\/","FileID":-2147483648,"URL":"","Mode":1,"Type":2,"Status":1,"CreatedOnDate":"\/Date(1388093500883)\/","UpdatedOnDate":"\/Date(1388093500883)\/","Inactive":false,"Deleted":true},
{"BatchIDs":[],"HomeWorkCategoryName":"","FileURL":"","FileName":"","ID":1,"Title":"test","Description":"test","HomeworkCategoryID":1,"ExpiryDate":"\/Date(1386658800000)\/","FileID":-2147483648,"URL":"","Mode":1,"Type":2,"Status":1,"CreatedOnDate":"\/Date(1388093500883)\/","UpdatedOnDate":"\/Date(1388093500883)\/","Inactive":false,"Deleted":true}]
And I want to read all values passed in this xml. This xml is single string return by web service. Currently I am using following code (it's also providing null value for first entry)
Object result = envelope.getResponse();
str=result+"";
String key,value;
String[] couple = str.split(",\"");
for(int i =0; i < couple.length ; i++) {
String[] items =couple[i].split(":");
key=items[0];
value=items[1];
key=key.replaceAll("\"", "");
value=value.replaceAll("\"", "");
/* some conditions to fetch values */
}
Please tell me how can I get exact values and keys in android.
Thanks,
It seems to be a valid json. You can use http://jsonlint.com/ to check that.
So with this following class : JSONArray, you can retrieve what you want.
Thanks everyone for helping me.
Here is my soluction through I overcome my problem. May be it will use for others
HttpGet httpRequest = new HttpGet(_URL);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse httpresponse = httpclient.execute(httpRequest);
JSONArray response = null;
try {
response = new JSONArray(getJSONString(httpresponse));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < response.length(); i++) {
try {
//your values
String _name=response.getJSONObject(i).getString("NAME");
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Here is 2nd function.If your function is parse through xml code.
public static String getJSONString(HttpResponse response) {
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(response.getEntity().getContent());
NodeList nl = doc.getElementsByTagName("string");
Node n = nl.item(0);
String str = n.getFirstChild().getNodeValue();
return str;
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
Happy Coding

Java - Jackson to a file

I have a JSON file like this:
{
"Product":
{
"ID": "08-17-96-71-D9-68",
"Licences":
{
"total": 40,
"used": 0,
"remain": 40
}
}
}
I used jackson to convert it to a Java Object and I get all the values (so far, so good).
My problem is that I want to change these values and re-write the JSON file but when I do that, the result is like this:
"{\"Product\":{\"IaD\": \"08-17-96-71-D9-68\",\"Licences\":{\"total\": 40,\"used\": 1,\"remain\": 39}}}"
So when I tried to read it again it gives me an error because it cannot read the first and last character (") and also it reads the \ character.
This is my code:
public class UsingJason {
String theJsonString = "";
ObjectMapper mapper = new ObjectMapper();
public class Product{
Licences lic;
public class Licences{
int total;
int used;
int remain;
}
}
public void readJson(){
if(new File("asset/testJson.json").exists()){
theJsonString = "";
try {
BufferedReader in = new BufferedReader(new FileReader("asset/testJson.json"));
String line;
while ((line = in.readLine()) != null){
theJsonString += line;
}
in.close();
} catch (IOException e1) {
e1.printStackTrace();
}
System.out.println("JSON String: "+ theJsonString);
}else{
System.out.println("NO FILE FOUND");
}
JsonNode rootNode = null;
try {
rootNode = mapper.readValue(theJsonString, JsonNode.class);
} catch (JsonParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (JsonMappingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
JsonNode totalNode = rootNode.get("Product").get("Licences").get("total");
JsonNode usedNode = rootNode.get("Product").get("Licences").get("used");
JsonNode remainNode = rootNode.get("Product").get("Licences").get("remain");
JsonNode idStringNode = rootNode.get("Product").get("ID");
// Parse it into a Java object.
try {
int totalObject = mapper.readValue(totalNode, Integer.class);
System.out.println("INTEGER? HAS TO BE... 40: "+totalObject);
String idString = mapper.readValue(idStringNode, String.class);
System.out.println("String? Has to be 08-17-96-71-D9-68: "+idString + " True? "
+ idString.equals("08-17-96-71-D9-68") );
int usedObject = mapper.readValue(usedNode, int.class);
int remainObject = mapper.readValue(remainNode, int.class);
System.out.println("Going to rest 1");
usedObject ++;
remainObject = totalObject - usedObject;
String toJackson = "{\"Product\":{\"I\\D\": \"08-17-96-71-D9-68\",\"Licences\":{\"total\": "+totalObject+",\"used\": "+usedObject+",\"remain\": "+remainObject+"}}}";
System.out.println("String created: " +toJackson);
// THIS toJackson String returns the string without \ and without the "
// IT PRINT THIS: {"Product":{"ID": "08-17-96-71-D9-68","Licences":{"total": 40,"used": 1,"remain": 39}}}
// EXACTLY WHAT I WANT TO Write in the Json file but it writes the \ ..
mapper.writeValue(new File("asset/testJson.json"), toJackson);
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Can anyone tell me what I am doing wrong?
In your code here:
mapper.writeValue(new File("asset/testJson.json"), toJackson);
You are serializing not an object, but the string to the file. I suppose this is the reason why it gets escaped, like any string.
The input value should be an object with your structure.
Something like this:
// Initialize an object
Product myProduct = new Product();
myProduct.lic = new Procuct.Licences();
myProduct.lic.total = totalObject;
myProduct.lic.used = usedObject;
myProduct.lic.remain = remainObject;
// Serialize the object into JSON
mapper.writeValue(new File("asset/testJson.json"), myProduct);

runtime exception for xpath

i have a function which in this function, i use Xpath to get the position of a node as below:
Node goTo;
.....
private Node xpathgo(Node node) throws XPathExpressionException {
XPath xpath = XPathFactory.newInstance().newXPath();
Node result;
if (node == null || node.getNodeName() == null){
return null;
}
xpathgo(node.getFirstChild());
result = (Node) xpath.evaluate("//*[. = \"" + goTo.getNodeValue() + "\"]", node,XPathConstants.NODE);
xpathgo(node.getNextSibling());
return result;
}
basically i use this to get a node of a DOM which made from a URL html code, but i face two problems with it, firstly, sometimes i get this exception:
Exception in thread "main" java.lang.RuntimeException: Could not resolve the node to a handle
at com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault.getDTMHandleFromNode(DTMManagerDefault.java:574)
at com.sun.org.apache.xpath.internal.XPathContext.getDTMHandleFromNode(XPathContext.java:182)
at com.sun.org.apache.xpath.internal.XPath.execute(XPath.java:301)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(XPathImpl.java:210)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:275)
and also this one for some other kind of nodes:
Caused by: javax.xml.transform.TransformerException: Expected ], but found: the
at com.sun.org.apache.xpath.internal.compiler.XPathParser.error(XPathParser.java:608)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.consumeExpected(XPathParser.java:526)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.Predicate(XPathParser.java:1935)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.Step(XPathParser.java:1724)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.RelativeLocationPath(XPathParser.java:1624)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.LocationPath(XPathParser.java:1595)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.PathExpr(XPathParser.java:1315)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnionExpr(XPathParser.java:1234)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnaryExpr(XPathParser.java:1140)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.MultiplicativeExpr(XPathParser.java:1061)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.AdditiveExpr(XPathParser.java:1003)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.RelationalExpr(XPathParser.java:928)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.EqualityExpr(XPathParser.java:868)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.AndExpr(XPathParser.java:832)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.OrExpr(XPathParser.java:805)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.Expr(XPathParser.java:788)
at com.sun.org.apache.xpath.internal.compiler.XPathParser.initXPath(XPathParser.java:127)
at com.sun.org.apache.xpath.internal.XPath.<init>(XPath.java:176)
at com.sun.org.apache.xpath.internal.XPath.<init>(XPath.java:264)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(XPathImpl.java:193)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:275)
... 7 more
but the funny thing is, in booth cases, the nodes are a [#text] node which made me confused why it happens.
I've made a function that returns the position of the node as you want :
test.xml
<html>
<div id='teste'>Teste</div>
<div id='poutine'>poutine</div>
<div id='ola'>Ola tudo ebm!</div>
</html>
XMLManager Class :
public final class XMLManager {
public static Integer getPositionByNode(Node node, File filteForLookUp){
Integer position = null;
try {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(filteForLookUp);
NodeList ndList = doc.getElementsByTagName("*");
if(ndList != null){
for(int i=0;i<ndList.getLength();i++){
if(ndList.item(i).isEqualNode(node)){
position = i;
System.out.println("Dans la condition");
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return position;
}
}
my Main :
public class MyMain {
/**
* #param args
*/
public static void main(String[] args) {
Document doc = null;
File file = new File("D:\\Loic_Workspace\\Test2\\res\\test.xml");
try {
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
System.out.println(doc.getElementsByTagName("*").item(2).getTextContent());
System.out.println(XMLManager.getPositionByNode(doc.getElementsByTagName("*").item(2), file));
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Output in the console :
poutine
Dans la condition
2
By the way is not weird to get [#text], you can't get the value by getTextContent() method.
Hope it's helps ;)

Categories