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
Related
I am new with Java programming and I have problem reading XML-file. I am trying to save information from XML using DOM parser. I load the xml into a Document and then trying to save all the schedules of a radio channel in a NodeList. but the program saves repeatedly just infromation of the first node. Where is the problem with my code ?
NodeList episodeElement = doc.getElementsByTagName("schedule");
for (int i = 0; i < episodeElement.getLength(); i++) {
Node n = episodeElement.item(i);
if (n.getNodeType() == Node.ELEMENT_NODE && getSize(doc) != 0) {
Element e = (Element) n;
String title = e.getElementsByTagName("title").item(i).getTextContent();
NodeList nd = e.getElementsByTagName("description");
String description;
if (nd.getLength() > 0) {
description = nd.item(i).getTextContent();
}else {
description = null;
}
String startTime = e.getElementsByTagName("starttimeutc").item(i).getTextContent();
String endTime = e.getElementsByTagName("endtimeutc").item(i).getTextContent();
Program prog = new Program(id, title, description, startTime, endTime);
System.out.println(startTime);
programs.add(i, prog);
}
else {
System.out.println("No schedules found");
}
}
You haven't used .getChildNodes() method to traverse a layer down the tag and looped around that, that's why it is just fetching you information of the first node.
Visit this link and u can find an excellent example.
https://www.youtube.com/watch?v=HfGWVy-eMRc
I am facing some problem while parsing my xml using JDOM parser.It gives me the commented lines when I am trying to retrieve the content.Is there a way so that we can ignore these commented lines.
Java Code:
SAXBuilder jdomBuilder = new SAXBuilder();
// jdomDocument is the JDOM2 Object
Document jdomDocument = jdomBuilder.build("C:/manu/WebservicesWS/DynamicXmlParse/src/PO_XML.xml");
// The root element is the root of the document. we print its name
System.out.println(jdomDocument.getRootElement().getName()); // prints
// "rss"
Element rss = jdomDocument.getRootElement();
System.out.println(rss.getNamespaceURI());
List<Element> rssChildren = rss.getChildren();
// getElement(rssChildren);
for (int i = 0; i < rssChildren.size(); i++) {
Element rssChild = rssChildren.get(i);
System.out.println(rssChild.getName());// prints 'title' and 'link'
List<Content> rssContents = rssChild.getContent();
for (int j = 0; j < rssContents.size(); j++) {
Content content = rssContents.get(j);
System.out.println(content.getValue());
}
}
XML Structure
<interchange-control-header>
<control-number>2</control-number>
<sender-id>ZZ:IQAAOBUYER7</sender-id>
<receiver-id>ZZ:33347456972</receiver-id>
<!--sender-id>ZZ:IQAAOBUYER2</sender-id>
<receiver-id>ZZ:IQAAOSUPPLIER2</receiver-id>
<sender-id>IQAOrionBuyer</sender-id>
<receiver-id>IQAOrionSupplier</receiver-id-->
<date-time>2012-06-29T09:30:47-05:00</date-time>
<control-version>1</control-version>
<usage-indicator>T</usage-indicator>
<is-copy>0</is-copy>
</interchange-control-header>
current Output
interchange-control-header
2
ZZ:IQAAOBUYER7
ZZ:33347456972
sender-id>ZZ:IQAAOBUYER2</sender-id>
<receiver-id>ZZ:IQAAOSUPPLIER2</receiver-id>
<sender-id>IQAOrionBuyer</sender-id>
<receiver-id>IQAOrionSupplier</receiver-id
2012-06-29T09:30:47-05:00
1
T
0
required Output:
interchange-control-header
2
ZZ:IQAAOBUYER7
ZZ:33347456972
2012-06-29T09:30:47-05:00
1
T
0
Comments are considered to be an identifiable part of an XML document, along with the more obvious things like Elements. Other content to be aware of are Processing Instructions, Text, and Entity References.
When you call getContent on the rssChild Element, you get the Comment content, and it's value is the text inside that content.
It appears you just want to print out the text content of each child element, not of all content.
The simple way to get all child elements is to use the getChildren() method (instead of the getContent). You are already using the getChildren in other places, so I am not sure why you forgot to use it here....
Additionally, you can simplify the loops to be for-each style... this code:
List<Element> rssChildren = rss.getChildren();
// getElement(rssChildren);
for (int i = 0; i < rssChildren.size(); i++) {
Element rssChild = rssChildren.get(i);
System.out.println(rssChild.getName());// prints 'title' and 'link'
List<Content> rssContents = rssChild.getContent();
for (int j = 0; j < rssContents.size(); j++) {
Content content = rssContents.get(j);
System.out.println(content.getValue());
}
}
could be:
for (Element rssChild : rss.getChildren()) {
System.out.println(rssChild.getName());// prints 'title' and 'link'
for (Element subRss : rssChild.getChildren()) {
System.out.println(subRss.getValue());
}
}
I want to read a multi level tags from xml(DOM) using java and the sample xml is : <root>
<subclass>
<subclass>
<subclass>
<name>test1</name>
<address>address1</address>
</subclass>
<name>test2</name>
<address>address2</address>
</subclass>
<name>test3</name>
<address>address3</address>
</subclass>
</root>
How to read <name>test2</name> and <address>address2</address> from the above xml?
I have given a sample code .. but i need to find the values dynamically.
when i am iterating bu using subclass tag, it's giving all the data. just i want to know how to get the specific data like <name>test2</name> and <address>address2</address> .
Below is my java code which is reading the above xml:
NodeList fList = firstWordElement
.getElementsByTagName("root");
for (int i = 0; i < fList.getLength(); i++) {
Node firstFLNode = fList.item(i);
if (firstFLNode.getNodeType() == Node.ELEMENT_NODE) {
Element firstWdElement = (Element) firstFLNode;
NodeList firstWdList = firstWdElement.getElementsByTagName("innerclass");
for (int j = 0; j < firstWdList.getLength(); j++) {
Element firstWd1Element = (Element) firstWdList.item(j);
if (firstWd1Element.getNodeType() == Node.ELEMENT_NODE) {
String InnerName = ParseUtil.getTagValue("name", firstWd1Element);
String InnerFormat = ParseUtil.getTagValue("format", firstWd1Element);
String InnerDescription = ParseUtil.getTagValue("description", firstWd1Element);
NodeList innerClassList = firstWd1Element.getElementsByTagName("subclass");
for (int k = 0; k < innerClassList.getLength(); k++) {
Element subClassElement = (Element) innerClassList
.item(k);
if (subClassElement.getNodeType() == Node.ELEMENT_NODE) {
String InnerSubName = ParseUtil.getTagValue("name", subClassElement);
System.out.println("Innername==="+ InnerSubName);
String InnerSubFormat = ParseUtil.getTagValue("format", subClassElement);
System.out.println("Innerformat==="+ InnerSubFormat);
String InnerSubDescription = ParseUtil.getTagValue("description", subClassElement);
System.out.println("Innerdescription==="+ InnerSubDescription);
}
}
}
}
}
}
A quick way to do this is by using XPath queries. Check out these tutorials:
http://www.ibm.com/developerworks/library/x-javaxpathapi/index.html
http://www.javabeat.net/2009/03/how-to-query-xml-using-xpath/
Traditionally you have to iterate trough the nodes, usually done by creating a NodeList with getChildren() from the parent node. If you only want the test2 -node you have to perform some sort of comparison - you can't jump straight to the second node. That is to say you can, but that wont make a very robust or scale able solution.
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#####");
}
}
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;