traversing DOM parsed XML [duplicate] - java

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Traversing complex xml File in android
In this i am parsing an xml file using DOM parser which is giving me dom1 as the parsed document.
the problem is that i want to create UI after this,and i am unable to the same as i can't find a logic to the same please help me with that.Also this is giving me wrong getLength() values. What is wrong with it??
the xml is in this link:
http://nchc.dl.sourceforge.net/project/trialxml/options.xml
//this is function is called when i click my button
public void next123(View view){
Element root=dom1.getDocumentElement();
NodeList nodes=root.getChildNodes();
create_Menu(nodes);
}
public void create_Menu(NodeList nodes){
for(int i=0;i<nodes.getLength();i++){
Node node=nodes.item(i);
if(node instanceof Element){
Element child = (Element)node;
String name=getTextValue(child,"Name");
String typ=child.getAttribute("type");
if(name!=null){
z++;
Log.i(TAG,"Names are:= " +name+ " -> "+typ +" -> "+ z+ " -> "+ i);
NodeList nod=child.getChildNodes();
Log.i(TAG,"Length : "+nod.getLength());
create_Menu(nod);
Log.i(TAG,"end");
}
}
}
}
i have to create a UI after this, for that i am using ListView and an array of ArrayList to store my values. the problem is i have to assign a no. to every level,
for example if my array is test[], then
test[0]-> main,
test[1]->1L1,1L2,1L3,
test[2]->2L1,
test[3]->2L2
test[4]->3L1,3L2
please the xml for refrence.

I am just giving an example, try to do it this way....
DocumentBuilderFactory odbf = DocumentBuilderFactory.newInstance();
DocumentBuilder odb = odbf.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
Document odoc = odb.parse(is);
odoc.getDocumentElement().normalize (); // normalize text representation
System.out.println ("Root element of the doc is " + odoc.getDocumentElement().getNodeName());
NodeList LOP = odoc.getElementsByTagName("locations");
int totalPersons =LOP.getLength();
System.out.println("Total nos of locations:"+totalPersons);
for(int s=0; s<LOP.getLength() ; s++)
{
Node FPN =LOP.item(s);
if(FPN.getNodeType() == Node.ELEMENT_NODE)
{
Element latlon = (Element)FPN;
NodeList oNameList1 = latlon.getElementsByTagName("featured");
Element firstNameElement = (Element)oNameList1.item(0);
NodeList textNList1 = firstNameElement.getChildNodes();
featuredArr = changeToBoolean(((Node)textNList1.item(0)).getNodeValue().trim()); // value taken
System.out.println("#####The Parsed data#####");
System.out.println("featured : " + ((Node)textNList1.item(0)).getNodeValue().trim());
System.out.println("#####The Parsed data#####");
}
}

Related

convert XML to a custom Excel with Java

I need advise about how to convert XML to a custom Excel with Java
I need to convert XML to Excel with a custom layout. I found a POI and it seems like it can help with this task. But I don't have this experiences and as I understood POI works the best with in memory trees like DOM. I started to pars my XML(I can show a small part of, it's really big and goes deep)
<advantage>
<companies>
<name>Name1</name>
<name>Name2</name>
<name>Name3</name>
<name>Name4</name>
<name>Name6</name>
</companies>
<companyPreCode>
<PreCode>1</PreCode>
<PreCode>2</PreCode>
<PreCode>3</PreCode>
<PreCode>4</PreCode>
<PreCode>6</PreCode>
</companyPreCode>
by using DOM as I saw in one online tutorial like this
Document xmlDoc = getDocument("./src/xmlForTest.xml");
xmlDoc.getDocumentElement().normalize();
System.out.println("Root element of the doc is :\" "+ xmlDoc.getDocumentElement().getNodeName() + "\"");
NodeList listOfAdvantage = xmlDoc.getElementsByTagName("advantage"); //first we need to find total number of Advantage blocks
int totalAdvantage = listOfAdvantage.getLength();
System.out.println("Total no of advantage : " + totalAdvantage);
for (int s = 0; s < listOfAdvantage.getLength(); s++) //get into advantage
{
Node AdvantageNode = listOfAdvantage.item(s);
System.out.println("advantage number : " + s);
if (AdvantageNode.getNodeType() == Node.ELEMENT_NODE)
{
Element AdvantageElement = (Element) AdvantageNode;
NodeList CompanyList = AdvantageElement.getElementsByTagName("companies"); // find node companies
System.out.println("companies number : " + CompanyList.getLength());
for(int cl = 0; cl < CompanyList.getLength(); cl++) {
NodeList CompanyNameList = CompanyList.item(cl).getChildNodes(); //AdvantageElement.getElementsByTagName("name");
for (int j = 0; j < CompanyNameList.getLength(); j++) {
Node childNode = CompanyNameList.item(j);
if ("name".equals(childNode.getNodeName())) {
for (int nl = 0; nl < CompanyNameList.getLength(); nl++) {
Element CompanyNameElement = (Element) CompanyNameList.item(nl);
NodeList textFNList = CompanyNameElement.getChildNodes();
System.out.println("Company: " + nl + " :" + (textFNList.item(0)).getNodeValue().trim());
CompaniesNames.add((textFNList.item(0)).getNodeValue().trim());
}
}
}
}
}// end of if clause
}// end of for loop with s var
and now I have several questions
How to make this parsing easier? my file is big and in some places I Have the same tags for different things, like Name can be for company, product or a person. But it's getting hard to retrieve it one by one the way I did it
How to feed this data later into POI so I can start using this POI to build my Excel files? Because right now I have a set of ArrayLists with my data from different tags and I just don't know what I need to next with it

navigating hierarchy of xml input file

How do I list the element names at a given level in an xml schema hierarchy? The code I have below is listing all element names at every level of the hierarchy, with no concept of nesting.
Here is my xml file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="CDA.xsl"?>
<SomeDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:something">
<title>some title</title>
<languageCode code="en-US"/>
<versionNumber value="1"/>
<recordTarget>
<someRole>
<id extension="998991"/>
<addr use="HP">
<streetAddressLine>1357 Amber Drive</streetAddressLine>
<city>Beaverton</city>
<state>OR</state>
<postalCode>97867</postalCode>
<country>US</country>
</addr>
<telecom value="tel:(816)276-6909" use="HP"/>
</someRole>
</recordTarget>
</SomeDocument>
Here is my java method for importing and iterating the xml file:
public static void parseFile() {
//get the factory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
//Using factory get an instance of document builder
DocumentBuilder db = dbf.newDocumentBuilder();
//parse using builder to get DOM representation of the XML file
Document dom = db.parse("D:\\mypath\\somefile.xml");
//get the root element
Element docEle = dom.getDocumentElement();
//get a nodelist of elements
NodeList nl = docEle.getElementsByTagName("*");
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
System.out.println("node.getNodeName() is: "+node.getNodeName());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
The output of the above program is:
title
languageCode
versionNumber
recordTarget
someRole
id
addr
streetAddressLine
city
state
postalCode
country
telecom
Instead, I would like to output the following:
title
languageCode
versionNumber
recordTarget
It would be nice to then be able to list the children of recordTarget as someRole, and then to list the children of someRole as id, addr, and telecom. And so on, but at my discretion in the code. How can I change my code to get the output that I want?
You're getting all nodes with this line:
NodeList nl = docEle.getElementsByTagName("*");
Change it to
NodeList nl = docEle.getChildNodes();
to get all of its children. Your print statement will then give you the output you're looking for.
Then, when you iterate through your NodeList, you can choose to call the same method on each Node you create:
NodeList children = node.getChildNodes();
If you want to print an XML-like structure, perhaps a recursive method that prints all child nodes is what you are looking for.
You could re-write the parseFile (I'd rather call it parseChildrenElementNames) method to take an input String that specifies the element name for which you want to print out its children element names:
public static void parseChildrenElementNames(String parentElementName) {
// get the factory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// Using factory get an instance of document builder
DocumentBuilder db = dbf.newDocumentBuilder();
// parse using builder to get DOM representation of the XML file
Document dom = db
.parse("D:\\mypath\\somefile.xml");
// get the root element
NodeList elementsByTagName = dom.getElementsByTagName(parentElementName);
if(elementsByTagName != null) {
Node parentElement = elementsByTagName.item(0);
// get a nodelist of elements
NodeList nl = parentElement.getChildNodes();
if (nl != null) {
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
System.out.println("node.getNodeName() is: "
+ node.getNodeName());
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
However, this will only consider the first element that matches the specified name.
For example, to get the list of elements under the first node named someRole, you would call parseChildrenElementNames("someRole"); which would print out:
node.getNodeName() is: id
node.getNodeName() is: addr
node.getNodeName() is: telecom

Read values from a complex xml using java

HI I am new to Java and trying to read an XML file.
Here is my XML file :-
<?xml version="1.0" encoding="UTF-8"?>
<parameter>
<attribute>a</attribute>
Here is my code I am trying to read the key and value from the xml but I am stuck .Here is my code :-
public class TestDBMain {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
File file = new File("ACL.xml");
DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbfactory.newDocumentBuilder();
Document doc = builder.parse(file);
NodeList nList = doc.getElementsByTagName("testCaseDataName");
for(int i = 0;i<nList.getLength();i++){
Node nNode = nList.item(i);
if(nNode.getNodeType()== Node.ELEMENT_NODE){
Element ele = (Element) nNode;
// System.out.println(ele.getTextContent());
//System.out.println(ele.getElementsByTagName("testCaseName").item(0).getTextContent());
System.out.println(ele.getAttributeNode("testCaseDataName"));
//I dont know which methods to use to print the key and value in the xml under parameter
}
}
}
}
Can anyone please help me with this
Disclaimer: I maintain the JDOM project, so I am biased.... but... this is an ideal use case for JDOM:
Document doc = new SAXBuilder().build(new File("ACL.xml"));
Element root = doc.getRootElement();
for (Element testcase : root.getChildren()) {
int id = Integer.parseInt(testcase.getChildText("id"));
String name = testcase.getChildText("testCaseName");
String expect = testcase.getChildText("expectedResult");
Map<String,String> params = new LinkedHashMap<String,String>();
Element parmemt = testcase.getChild("parameter");
if (parmemt != null) {
Iterator<Element> it = parmemt.getChildren().iterator();
while (it.hasNext()) {
Element key = it.next();
if (!"key".equals(key.getName())) {
throw new IllegalStateException("Expected key but got " + key);
}
if (!it.hasNext()) {
throw new IllegalStateException("Expected value for key " + key);
}
Element val = it.next();
if (!"value".equals(val.getName())) {
throw new IllegalStateException("Expected value but got " + val);
}
params.put(key.getValue(), val.getValue());
}
}
System.out.printf("Processing test case %d -> %s\n Expect %s\n Parameters: %s\n",
id, name, expect, params.toString());
}
For me this produces the output
Processing test case 1 -> EditTest
Expect nooptionsacltrue
Parameters: {}
Processing test case 2 -> AddTest
Expect featuresaddedacltrue
Parameters: {featues=w,f}
Processing test case 3 -> AddTest
Expect duplicateacltrue
Parameters: {projectType=NEW, Name=28HPM, status=ACTIVE, canOrder=Yes}
your code read <testCaseDataName> node. it is not go inside of this tag.
so try this..
for(int i = 0;i<nList.getLength();i++){
NodeList nodeList = nList.item(i).getChildNodes();
for(int j = 0;j<nList.getLength();j++){
Node nNode = nodeList.item(j);
if(nNode.getNodeType()== Node.ELEMENT_NODE){
System.out.println(nNode.getNodeName() +" : "+nNode.getTextContent());
if(nNode.getNodeName().equals("parameter")){
NodeList param = nNode.getChildNodes();
System.out.println(" "+param.item(0).getNodeName() +" : "+param.item(0).getTextContent());
System.out.println(" "+param.item(1).getNodeName() +" : "+param.item(1).getTextContent());
}
}
}
}

how to get attribute of given node?

I am trying to write DOM XML parsing.
My Xml file
<?xml version="1.0"?>
<BLAH>
<AgentNm type="citi1">
<accName>accName1</accName>
<accType>accType1</accType>
<someThing>someThing1</someThing>
<amt>100000</amt>
</AgentNm>
<AgentNm type="citi2">
<accName>accName2</accName>
<accType>accType2</accType>
<someThing>someThing2</someThing>
<amt>200000</amt>
</AgentNm>
</BLAH>
And i tried following java code
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse (new File("c:\\file.xml"));
// normalize text representation
doc.getDocumentElement ().normalize ();
System.out.println ("Root element of the doc is " +doc.getDocumentElement().getNodeName());
NodeList agentNm = doc.getElementsByTagName("AgentNm");
int totalAgentNm = agentNm.getLength();
System.out.println("Total no of Agents : " + totalAgentNm);
for(int s=0; s<agentNm.getLength() ; s++){
Node firstPersonNode = agentNm.item(s);
if(firstPersonNode.getNodeType() == Node.ELEMENT_NODE){
Element firstPersonElement = (Element)firstPersonNode;
PrintNodeElem(firstPersonElement,"type");
}//end of if clause
}//end of for loop with s var
static void PrintNodeElem(Element nodeElem,String elem){
NodeList someThingList = nodeElem.getElementsByTagName(elem);
Element ageElement = (Element)someThingList.item(0);
NodeList textAgeList = ageElement.getChildNodes();
System.out.println(elem+" : " +((Node)textAgeList.item(0)).getNodeValue().trim());
}
But, when i tried to execute above method,
i am getting null pointer exception.
can any one explain me, how to fix this.
if you want an attribute of a given node, I would suggest XPath. It is much easier.
http://onjava.com/onjava/2005/01/12/xpath.html

Parsing xml string containing hyperlink

I am using DOM to parse an XML string as in the following example. This works great except in one instance. The document which I am trying to parse looks like this:
<response requestID=\"1234\">
<expectedValue>Alarm</expectedValue>
<recommendations>For steps on how to resolve visit Website and use the search features for \"Alarm\"<recommendations>
<setting>Active</setting>
<response>
The code I used to parse the XML is as follows:
try {
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlResult));
Document doc = db.parse(is);
NodeList nlResponse = doc.getElementsByTagName("response");
String[] String = new String[3]; //result entries
for (int i = 0; i < nlResponse.getLength(); i++) {
Element e = (Element) nlResponse.item(i);
int c1 = 0; //count for string array
NodeList ev = e.getElementsByTagName("expectedValue");
Element line = (Element) ev.item(0);
String[c1] = (getCharacterDataFromElement(line));
c1++;
NodeList rec = e.getElementsByTagName("recommendations");
line = (Element) rec.item(0);
String[c1] = (getCharacterDataFromElement(line));
c1++;
NodeList set = e.getElementsByTagName("settings");
line = (Element) set.item(0);
String[c1] = (getCharacterDataFromElement(line));
c1++;
I am able to parse the code and put the result into a string array (as opposed to the System.out.println()). With the current code, my string array looks as follows:
String[0] = "Alarm"
String[1] = "For steps on how to resolve visit"
String[2] = "Active"
I would like some way of being able to read the rest of the information within "Recommendations" in order to ultimately display the hyperlink (along with other output) in a TextView. How can I do this?
I apologize for my previous answer in assuming your xml was ill-formed.
I think what is happening is that your call to the getCharacterDataFromElement is only looking at the first child node for text, when it will need to look at all the child nodes and getting the href attribute as well as the text for the 2nd child node when looking at the recommendations node.
e.g. after getting the Element for recommendation
String srec = "";
NodeList nl = line.getChildNodes();
srec += nl.item(0).getTextContent();
Node n = nl.item(1);
NamedNodeMap nm = n.getAttributes();
srec += "" + n.getTextContent() + "";
srec += nl.item(2).getTextContent();
String[c1] = srec;

Categories