Java Programming
I have a class WeatherAgent. The function of this class is to get the current temperature value and other parameters from a URL (XML code) from World weather online.
My main question is; how to get the generated temperature value in class WeatherAgent into antother class (Boiler)? So, Accessing XML value in class WeatherAgent as a new variable in another class (class Boiler).
package assignment_4;
/*
* imports of class WeatherAgent2
*/
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/*
*start class WeatherAgent2
*/
public class WeatherAgent {
private Document getDocument() {
Document doc = null;
try {
URL url = new URL(
"http://api.worldweatheronline.com/free/v1/weather.ashx?q=Eindhoven&format=xml&num_of_days=5&key=87xdd77n893f6akfs6x3jk9s");
URLConnection connection = url.openConnection(); // Connecting to
// URL specified
doc = parseXML(connection.getInputStream());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return doc;
}
private Document parseXML(InputStream stream) throws Exception
{
DocumentBuilderFactory objDocumentBuilderFactory = null;
DocumentBuilder objDocumentBuilder = null;
Document doc = null;
try
{
objDocumentBuilderFactory = DocumentBuilderFactory.newInstance();
objDocumentBuilder = objDocumentBuilderFactory.newDocumentBuilder();
doc = objDocumentBuilder.parse(stream);
}
catch (Exception ex)
{
throw ex;
}
return doc;
}
/*
* get the temperature
*/
public double temperature() {
Document doc = getDocument();
Node Temperature;
Double temp = 0.0;
NodeList forecast = doc.getElementsByTagName("temp_C");
for (int i = 0; i < forecast.getLength(); i++) {
Element element = (Element) forecast.item(i);
NodeList list1 = (NodeList) element.getChildNodes();
Temperature = list1.item(0);
temp = Double.parseDouble(Temperature.getNodeValue());
}
return temp;
}
/*
* get cloud cover
*/
public double cloudcover() {
Document doc = getDocument();
Node Cloudcover;
Double cloudcover = 0.0;
NodeList forecast = doc.getElementsByTagName("cloudcover");
for (int i = 0; i < forecast.getLength(); i++) {
Element element = (Element) forecast.item(i);
NodeList list2 = (NodeList) element.getChildNodes();
Cloudcover = list2.item(0);
cloudcover = Double.parseDouble(Cloudcover.getNodeValue());
}
return cloudcover;
}
/*
* print method
*/
public static void main(String[] argvs) {
WeatherAgent wp = new WeatherAgent();
System.out.println("Temperature: " + wp.temperature());
System.out.println("Cloudcover: " + wp.cloudcover());
}
}
I have this methode in class Boiler to get the temperature value from class WeatherAgent into class Boiler.
It is not working and I do know why. Thanks already for your help!
public double getValueFromAgent(){
double agentTemp = send(URL.create("http://api.worldweatheronline.com/free/v1/weather.ashx?q=Eindhoven&format=xml&num_of_days=5&key=87xdd77n893f6akfs6x3jk9s", "temperature" , null, Double.class));
return agentTemp;
}
There are design patterns for how to structure your classes to share information like this. I'd look into the Observer pattern and the Mediator pattern.
Or in main, when you get the temperature from the WeatherAgent, push it into Boiler. With all of these, the idea is to decouple Boiler from knowing anything about WeatherAgent. It helps with reusability, and makes testing them independently a lot easier.
Related
I created below class with getter and setter.
import java.util.List;
public class DMNDetails {
private List<String> inputParam;
private List<String> outputParam;
public List<String> getInputParam() {
return inputParam;
}
public void setInputParam(List<String> inputParam) {
this.inputParam = inputParam;
}
public List<String> getOutputParam() {
return outputParam;
}
public void setOutputParam(List<String> outputParam) {
this.outputParam = outputParam;
}
#Override
public String toString() {
return ("Inputname: "+ getInputParam()+
" Outputname: "+ getOutputParam());
}
}
Extracting input and output variables from XML and return using List.
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class ExtractingValues {
public DMNDetails Param() {
List<String> inputval = new ArrayList<String>();
DMNDetails dtls = new DMNDetails();
String variables;
// String dataType;
try {
File file = new File("C:/test.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
// System.out.println("Root element: "+ doc.getDocumentElement().getNodeName());
NodeList nodeList = doc.getElementsByTagName("inputExpression");
for (int i = 0; i < nodeList.getLength(); ++i) {
Node node = nodeList.item(i);
// System.out.println("\nNode Name :" + node.getNodeName());
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element tElement = (Element)node;
variables = tElement.getElementsByTagName("text").item(0).getTextContent();
// dataType = tElement.getAttribute("typeRef");
// System.out.println("Variable: "+ variables);
// System.out.println("Type: "+ dataType);
switch(i) {
case 0:
inputval.add(variables);
// System.out.println("Input1: "+dtls1.getInput1());
break;
case 1:
inputval.add(variables);
// System.out.println("Input2: "+dtls2.getInput2());
break;
case 2:
inputval.add(variables);
// System.out.println("Input3: "+dtls3.getInput3());
break;
default:
System.out.println("Error");
}
}
}
}
catch (Exception e) {
System.out.println(e);
}
dtls.setInputParam(inputval);
/*** OutputVariable Section ***/
List<String> outputval = new ArrayList<String>();
String variablesout;
// String dataType;
try {
File file = new File("C:/Jira_task/Sprint_17/Business.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
// System.out.println("Root element: "+ doc.getDocumentElement().getNodeName());
NodeList nodeList2 = doc.getElementsByTagName("output");
for (int i = 0; i < nodeList2.getLength(); ++i) {
Node node2 = nodeList2.item(i);
// System.out.println("\nNode Name :" + node2.getNodeName());
if (node2.getNodeType() == Node.ELEMENT_NODE) {
Element tElement = (Element)node2;
variablesout = tElement.getAttribute("name");
// dataType = tElement.getAttribute("typeRef");
// System.out.println("Variable: "+ variables);
// System.out.println("Type: "+ dataType);
switch(i) {
case 0:
outputval.add(variablesout);
// System.out.println("Output1: "+dtls1.getOutput1());
break;
case 1:
outputval.add(variablesout);
// System.out.println("Output2: "+dtls2.getOutput2());
break;
case 2:
outputval.add(variablesout);
// System.out.println("Output3: "+dtls3.getOutput3());
break;
default:
System.out.println("Error");
}
}
}
}
catch (Exception e) {
System.out.println(e);
}
dtls.setOutputParam(outputval);
return dtls;
}
}
Here we are get data from "TestCase.xlsx" excel and store in data list and return. My expectation are written inside commented block inside.
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ReadExcelTestCase2 {
public static List<DMNRow> getdata() throws IOException {
List<DMNRow> data = new ArrayList<>();
// Reading file from local directory
FileInputStream file = new FileInputStream("C:\\TestCase.xlsx");
// Create Workbook instance holding reference to .xlsx file
XSSFWorkbook XS = new XSSFWorkbook(file);
int numberofsheets = XS.getNumberOfSheets();
for (int i = 0; i < numberofsheets; i++) {
if (XS.getSheetName(i).equalsIgnoreCase("Sheet1")) {
XSSFSheet XSS = XS.getSheetAt(i);
Iterator<Row> r = XSS.iterator();
/* Here input and output variables are hardcode, but cannot able to hardcode value here, because each xml file contain
n number of input and output. So according to n number of variables we need to extract data from excel and store data
in "data". Datatype also change for each variables.
String cr;
long lc;
String arn;
DMNRow DMNRow;
while (r.hasNext()) {
Row row = r.next();
if (row.getRowNum() == 0) {
continue;
}
cr = row.getCell(0).getStringCellValue();
lc = (long) row.getCell(1).getNumericCellValue();
DataFormatter formatter = new DataFormatter();
arn = formatter.formatCellValue(row.getCell(2));
DMNRow = new DMNRow(cr, lc, arn);
data.add(DMNRow);
*/
}
}
}
// Closing file output streams
XS.close();
file.close();
return data;
}
}
After data from excel store and return to another method to compare data with DMN engine and write status in same excel in Result column.
Can anyone please guide how to store data from excel into list to use by another method for compare.
this is the xml file
please how to parse the tag author example we dont know how many author for each inproceeding ?
<?xml version="1.0" encoding="ISO-8859-1"?>
<dblp>
<inproceedings mdate="2014-01-18" key="series/sci/AzzagL13">
<author>Hanane Azzag</author>
<author>Mustapha Lebbah</author>
<title>A New Way for Hierarchical and Topological Clustering.</title>
<pages>85-97</pages>
<year>2011</year>
<booktitle>EGC (best of volume)</booktitle>
<ee>http://dx.doi.org/10.1007/978-3-642-35855-5_5</ee>
<crossref>series/sci/2013-471</crossref>
<url>db/series/sci/sci471.html#AzzagL13</url>
</inproceedings>
<inproceedings mdate="2014-01-18" key="series/sci/RabatelBP13">
<author>Julien Rabatel</author>
<author>Sandra Bringay</author>
<author>Pascal Poncelet</author>
<title>Mining Sequential Patterns: A Context-Aware Approach.</title>
<pages>23-41</pages>
<year>2011</year>
<booktitle>EGC (best of volume)</booktitle>
<ee>http://dx.doi.org/10.1007/978-3-642-35855-5_2</ee>
<crossref>series/sci/2013-471</crossref>
<url>db/series/sci/sci471.html#RabatelBP13</url>
</inproceedings>
</dblp>
Use Xpath, it's fast and powerfull , these lines for your example return 5 lines
Code:
final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new FileInputStream("input.xml"));
final XPath xPath = XPathFactory.newInstance().newXPath();
final NodeList nodeList = (NodeList) xPath.compile("//author").evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
Displays:
Hanane Azzag
Mustapha Lebbah
Julien Rabatel
Sandra Bringay
Pascal Poncelet
Following code parse using apache digester which is commonly used while parsing in real projects. Nice one from apache community
// Updated code as per you need.
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.Rules;
import org.xml.sax.InputSource;
public class Parsing {
public static void main(String[] args) throws Exception{
InputStream data = new FileInputStream("E:\\workspace\\trunk\\Parsing\\src\\data.xml");
byte[] b = new byte[data.available()];
// data.read(b);
Digester digester = new Digester();
//Genearting Array list while encountering dblp xpath
digester.addObjectCreate("dblp", HashMap.class);
digester.addObjectCreate("dblp/inproceedings", ArrayList.class);
//Calling add method while encountering author xpath
AuthorRule rule = new AuthorRule();
digester.addRule("dblp/inproceedings/author", rule);
digester.addRule("dblp/inproceedings/title", rule);
digester.addRule("dblp/inproceedings", rule);
HashMap parsedData = (HashMap) digester.parse(data);
Iterator<Entry<String, ArrayList>> dataItr = parsedData.entrySet().iterator();
while(dataItr.hasNext()){
Entry<String, ArrayList> entry = dataItr.next();
System.out.println("Title : " + entry.getKey() + ", Authors" + entry.getValue().toString());
}
}
private static class AuthorRule extends Rule{
String currentTitle = "";
#Override
public void body(String namespace, String name, String text)
throws Exception {
HashMap object = (HashMap) digester.peek(1);
ArrayList authors = (ArrayList) digester.peek(0);
if(name.equals("title")){
currentTitle = text;
}
else if(name.equals("author")){
authors.add(text);
}
}
#Override
public void end(String namespace, String name) throws Exception {
HashMap object = (HashMap) digester.peek(1);
ArrayList authors = (ArrayList) digester.peek(0);
if(name.equals("inproceedings")){
object.put(currentTitle, authors);
}
}
}
}
output::
Title : A New Way for Hierarchical and Topological Clustering., Authros[Hanane Azzag, Mustapha Lebbah]
Title : Mining Sequential Patterns: A Context-Aware Approach., Authros[Julien Rabatel, Sandra Bringay, Pascal Poncelet]
there are number of ways, e.g. via DOM:
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
public class XmlAuthorReader {
public static void main(String argv[]) {
try {
File fXmlFile = new File(<filePath>);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
NodeList nList = doc.getElementsByTagName("author");
System.out.println(nList.getLength()+ " author(s) found");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("Author: " + nNode.getTextContent());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
you can find more variants here: http://www.mkyong.com/tutorials/java-xml-tutorials/
Im new in Java, and i have a task to Parse one xml file using http with current url http://belbooner.site40.net/testXmls/details.xml
I created Some class to parse it using Dom method, but im having java.lang.NullPointerException while trying to get one Nodes value
So here's the code
import java.security.KeyStore.Builder;
import java.util.*;
import java.io.*;
import java.net.*;
import javax.swing.text.Document;
import javax.xml.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.w3c.dom.*;
import org.w3c.dom.CharacterData;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class RequestResponse {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
URL url = new URL("http://belbooner.site40.net/testXmls/details.xml");
RequestResponse req= new RequestResponse();
req.getHTTPXml(url);
}
void getHTTPXml(URL url) throws ParserConfigurationException, IOException, SAXException {
//URL url = new URL("http://belbooner.site40.net/testXmls/details.xml");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("ACCEPT","application/xml");
InputStream xml = conn.getInputStream();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document document = builder.parse(xml);
System.out.println(document);
String doctype = conn.getContentType();
System.out.print(doctype);
NodeList root = document.getChildNodes();
Node server = getNodes("server",root);
Node check = getNodes("check", server.getChildNodes());
NodeList nodes = check.getChildNodes();
String checkid= getNodeValue("checkid", nodes);
System.out.println(checkid);
conn.disconnect();
//return (Document) DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xml);
}
Node getNodes(String tagName, NodeList nodes) {
for(int i=0; i< nodes.getLength();i++) {
Node node= nodes.item(i);
if(node.getNodeName().equalsIgnoreCase(tagName)) {
return node;
}
}
return null;
}
String getNodeValue(String tagName, NodeList nodes ) {
for ( int i = 0; i < nodes.getLength(); i++ ) {
Node node = nodes.item(i);
if (node.getNodeName().equalsIgnoreCase(tagName)) {
NodeList childNodes = node.getChildNodes();
for (int y = 0; y < childNodes.getLength(); y++ ) {
Node data = childNodes.item(y);
if ( data.getNodeType() == Node.TEXT_NODE ) {
return data.getNodeValue();
}
if(data instanceof CharacterData) {
CharacterData cd= (CharacterData) data;
return cd.getData();
}
}
}
}
return "";
}
}
The stacktrace I'm getting is the following:
application/xmlException in thread "main" java.lang.NullPointerException at
RequestResponse.getHTTPXml(RequestResponse.java:45) at
RequestResponse.main(RequestResponse.java:22)
After changin Node server = getNodes("server",root); to `
Node resultNode = getNodes("result", root);
Node server = getNodes("server", resultNode.getChildNodes());`
`application/xmlException in thread "main" java.lang.NullPointerException
at RequestResponse.getHTTPXml(RequestResponse.java:49)
at RequestResponse.main(RequestResponse.java:22)
`
Please help me to find the issue.
The problem is that Node server = getNodes("server",root); is returning null.
Why does this happen? Well look how you implemented getNodes
Node getNodes(String tagName, NodeList nodes) {
for(int i=0; i< nodes.getLength();i++) {
Node node= nodes.item(i);
if(node.getNodeName().equalsIgnoreCase(tagName)) {
return node;
}
}
return null;
}
You are giving as input the document root which is a single "Result" node, you iterate through it and you compare if the node's name is in this case "server" which never will be, hence you return null and get a NPE.
Your node look up must be done in the following way:
NodeList root = document.getChildNodes();
// Keep in mind that you have the following structure:
// result
// server
// checks
// check
// checkId
// check
// checkId
Node resultNode = getNodes("result", root);
Node server = getNodes("server", resultNode.getChildNodes());
Node checks = getNodes("checks", server.getChildNodes());
NodeList childNodes = checks.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node possibleCheck = childNodes.item(i);
if (possibleCheck.getNodeName().equals("check")) {
String checkid = getNodeValue("checkid", possibleCheck.getChildNodes());
System.out.println(checkid);
}
}
This way you'll be iterating through the correct node list.
Using XPath is more efficient and flexible (than normal iteration) while parsing xml.
XPath Tutorial from IBM
XPath Reference Orielly tutorial
Xpath Reference Oracle java tutorial
Try below code.
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class RequestResponse {
public static void main(String[] args) throws ParserConfigurationException,
IOException, SAXException {
URL url = new URL("http://belbooner.site40.net/testXmls/details.xml");
RequestResponse req = new RequestResponse();
req.getHTTPXml(url);
}
void getHTTPXml(URL url) throws ParserConfigurationException, IOException,
SAXException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("ACCEPT", "application/xml");
InputStream xml = conn.getInputStream();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document document = builder.parse(xml);
System.out.println(document);
String doctype = conn.getContentType();
System.out.println(doctype);
XPathFactory pathFactory = XPathFactory.newInstance();
XPath path = pathFactory.newXPath();
XPathExpression expression;
try {
expression = path.compile("/result/server/checks/check/checkid");
NodeList nodeList = (NodeList) expression.evaluate(document,
XPathConstants.NODESET);
String checkids[] = getNodeValue(nodeList);
for (String checkid : checkids) {
System.out.print(checkid + ", ");
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
conn.disconnect();
}
String[] getNodeValue(NodeList nodes) {
String checkIds[] = new String[nodes.getLength()];
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
checkIds[i] = node.getTextContent();
}
return checkIds;
}
}
im trying to get all element of an XML file and put it into a ArrayList>> with a recursive method, but i get an error : Exception in thread "main" java.lang.StackOverflowError at java.util.ArrayList.
the error is getting when i make a recursive call : GetAllXml(ListTree);
and i want to get a strcuture like this [[[un]] , [[deux,trois,quatre]] , [[cinq,six,sept],[huit,noeuf],[dix,onze]]]
here is my code:
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.NodeList;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
public class esperant {
/**
* #param args
*/
private static List<Element> getChildren(Node parent)
{
NodeList nl = parent.getChildNodes();
List<Element> children = new ArrayList<Element>(nl.getLength());
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
if (n instanceof Element)
children.add((Element) n);
}
return children;
}
public static void GetAllXml(ArrayList<ArrayList<ArrayList<Element>>> ListTree)
{
ArrayList<ArrayList<Element>> child = new ArrayList<ArrayList<Element>>();
int level = ListTree.size()-1;
for (int i=0;i<ListTree.get(level).size();i++)
{
for (int j=0;j<ListTree.get(level).get(i).size();j++)
{
ArrayList<Element> childOfChild = new ArrayList<Element>();
childOfChild.addAll(getChildren(ListTree.get(level).get(i).get(j)));
child.add(childOfChild);
}
}
ListTree.add(child);
GetAllXml(ListTree);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<ArrayList<ArrayList<Element>>> ListTree = new ArrayList<ArrayList<ArrayList<Element>>>();
ArrayList<ArrayList<Element>> child = new ArrayList<ArrayList<Element>>();
ArrayList<Element> childOfChild = new ArrayList<Element>();
try{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse("test.xml");
Element root = doc.getDocumentElement();
childOfChild.add(root);
child.add(childOfChild);
ListTree.add(child);
GetAllXml(ListTree);
System.out.println(ListTree);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
here is the xml file :
<?xml version="1.0" encoding="iso-8859-1"?>
<un>
<deux> <cinq></cinq> <six></six> <sept></sept> </deux>
<trois> <huit></huit><noeuf></noeuf> </trois>
<quatre><dix></dix><onze></onze> </quatre>
</un>
Change Your GetAllXml(X) like this, it would work. As Every one above said , there is no way out from this method.
final ArrayList<ArrayList<Element>> child = new ArrayList<ArrayList<Element>>();
final int level = ListTree.size() - 1;
for (int i = 0; i < ListTree.get(level).size(); i++)
{
for (int j = 0; j < ListTree.get(level).get(i).size(); j++)
{
final ArrayList<Element> childOfChild = new ArrayList<Element>();
childOfChild.addAll(getChildren(ListTree.get(level).get(i).get(j)));
if (childOfChild.size() > 0)
{
child.add(childOfChild);
}
}
}
if (child.size() > 0)
{
ListTree.add(child);
GetAllXml(ListTree);
}
Every call on GetAllXml(X), whatever else it does, ends up calling GetAllXml(X) passing the same value as its argument. So it's obvious that it will recurse infinitely.
I've written class to parse some xml into an object and it's not working correctly, when I try and get the value of a node I get a null rather than the contents of the node.
Here is a simplified version of my class that just does the xml parsing of a single node:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XmlReaderCutDown {
private static Logger logger = Logger.getLogger(CtiButtonsXmlReader.class);
public static void testXml(String confFile){
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new File(confFile));
doc.getDocumentElement().normalize();
if (logger.isDebugEnabled()){
logger.debug("The root element is " + doc.getDocumentElement().getNodeName());
}
NodeList rows = doc.getElementsByTagName("row");
NodeList topRowButtons = ((Element)rows.item(0)).getElementsByTagName("button");
logger.debug("Top row has " +topRowButtons.getLength() + " items.");
Node buttonNode = topRowButtons.item(0);
NodeList nodeList = ((Element)buttonNode).getElementsByTagName("id");
logger.debug("Node list count for "+ "id" + " = " + nodeList.getLength());
Element element = (Element)nodeList.item(0);
String xx = element.getNodeValue();
logger.debug(xx);
String elementValue = ((Node)element).getNodeValue();
if (elementValue != null) {
elementValue = elementValue.trim();
}
else {
logger.debug("Value was null");
}
logger.debug("Node id = "+ elementValue);
} catch (ParserConfigurationException e) {
logger.fatal(e.toString(),e);
} catch (SAXException e) {
logger.fatal(e.toString(),e);
} catch (IOException e) {
logger.fatal(e.toString(),e);
} catch (Exception e) {
logger.fatal(e.toString(),e);
}
}
public static void main(String[] args){
DOMConfigurator.configure("log4j.xml");
testXml("test.xml");
}
}
And here is a stripped down version of my xml file:
<?xml version="1.0"?>
<root>
<row>
<button>
<id>this is an id</id>
<action>action</action>
<image-src>../images/img.png</image-src>
<alt-text>alt txt</alt-text>
<tool-tip>Tool tip</tool-tip>
</button>
</row>
</root>
This is what the logging statments output:
DEBUG XmlReaderCutDown - The root element is root
DEBUG XmlReaderCutDown - Top row has 1 items.
DEBUG XmlReaderCutDown - Node list count for id = 1
DEBUG XmlReaderCutDown -
DEBUG XmlReaderCutDown - Value was null
DEBUG XmlReaderCutDown - Node id = null
Why isn't it getting the text in the xml node?
I'm running using JDK 1.6_10
Because the element you get is the parent element of the text one, containing the text you need. To access the text of this element, you shall use getTextContent instead of getNodeValue.
For more information, see the table in the Node javadoc.
See http://java.sun.com/j2se/1.5.0/docs/api/org/w3c/dom/Node.html . Element.getNodeValue() always returns null. You should use Element.getTextContent()
Consider using XPath as an alternative to manually walking nodes:
public static void testXml(String confFile)
throws XPathExpressionException {
XPathFactory xpFactory = XPathFactory.newInstance();
XPath xpath = xpFactory.newXPath();
NodeList rows = (NodeList) xpath.evaluate("root/row",
new InputSource(confFile), XPathConstants.NODESET);
for (int i = 0; i < rows.getLength(); i++) {
Node row = rows.item(i);
String id = xpath.evaluate("button/id", row);
System.out.println("id=" + id);
}
}
public static void main(String[] args)
throws XPathExpressionException {
testXml("test.xml");
}