Merging xml file using java NodeList - java

I'm trying to merge two xml files as shown below but i can't able to get the desired output please help me thank you
Java code:
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setIgnoringComments(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new File("file1.xml"));
Document doc1 = builder.parse(new File("file2.xml"));
NodeList nodes = doc.getElementsByTagName("staff");
NodeList nodes1 = doc1.getElementsByTagName("staff");
for(int i=0;i<nodes1.getLength();i=i+1){
Node n= (Node) doc.importNode(nodes1.item(i), true);
nodes.item(i).getParentNode().appendChild(n);
}
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
Writer output = null;
output = new BufferedWriter(new FileWriter("mergedxml.xml"));
String xmlOutput = result.getWriter().toString();
output.write(xmlOutput);
output.close();
System.out.println("merge complete");
File1.xml
<company>
<staff>
<name>john</name>
<phone>465456433</phone>
<email>gmail1</email>
</staff>
</company>
File2.xml
<company>
<staff>
<area>area1</area>
<city>city1</city>
</staff>
</company>
Current output:
<company>
<staff>
<name>john</name>
<phone>465456433</phone>
<email>gmail1</email>
</staff>
<staff>
<area>area1</area>
<city>city1</city>
</staff>
</company>
Expected Output:
<company>
<staff>
<name>john</name>
<phone>465456433</phone>
<email>gmail1</email>
<area>area1</area>
<city>city1</city>
</staff>
</company>

In order to do that on your own. You should do this following :
public static void mergeXML(){
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
Document doc = null;
Document doc2 = null;
try {
db = dbf.newDocumentBuilder();
doc = db.parse(new File("D:\\Loic_Workspace\\Test2\\res\\test.xml"));
doc2 = db.parse(new File("D:\\Loic_Workspace\\Test2\\res\\test2.xml"));
NodeList ndListFirstFile = doc.getElementsByTagName("staff");
Node nodeArea = doc.importNode(doc2.getElementsByTagName("area").item(0), true);
Node nodeCity = doc.importNode(doc2.getElementsByTagName("city").item(0), true);
ndListFirstFile.item(0).appendChild(nodeArea);
ndListFirstFile.item(0).appendChild(nodeCity);
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
Writer output = new BufferedWriter(new FileWriter("D:\\Loic_Workspace\\Test2\\res\\testFinal.xml"));
String xmlOutput = result.getWriter().toString();
output.write(xmlOutput);
output.close();
} 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 (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Final output of testFinal.xml :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<company>
<staff>
<name>john</name>
<phone>465456433</phone>
<email>gmail1</email>
<area>area1</area>
<city>city1</city>
</staff>
</company>
As you want it ;-)
Hope it helps,

This solution is for files where you need to iterate and verify something before to merge.
file1.xml:
<?xml version="1.0" encoding="UTF-8"?>
<reactions>
<reaction>
<ID>07402</ID>
<type>irreversible</type>
<substrate>15666</substrate>
<product>07756</product>
</reaction>
<reaction>
<ID>03063</ID>
<type>irreversible</type>
<substrate>00916</substrate>
<product>04712</product>
</reaction>
file2.xml:
<?xml version="1.0" encoding="UTF-8"?><reactions>
<reaction>
<ID>00001</ID>
<reactionName>polyphosphate polyphosphohydrolase</reactionName>
<reactionDescription> Polyphosphate + n H2O <=> (n+1) Oligophosphate</reactionDescription>
</reaction>
<reaction>
<ID>00002</ID>
<reactionName>Reduced ferredoxin:dinitrogen oxidoreductase (ATP-hydrolysing)</reactionName>
<reactionDescription> 16 ATP + 16 H2O + 8 Reduced ferredoxin <=> 8 e- + 16 Orthophosphate + 16 ADP + 8 Oxidized ferredoxin</reactionDescription>
</reaction>
<reaction>
<ID>03063</ID>
<reactionName>cephalosporin-C:2-oxoglutarate aminotransferase</reactionName>
<reactionDescription> Cephalosporin C + 2-Oxoglutarate <=> (7R)-7-(5-Carboxy-5-oxopentanoyl)aminocephalosporinate + D-Glutamate</reactionDescription>
</reaction>
<reaction>
<ID>07402</ID>
<reactionName>(7R)-7-(4-carboxybutanamido)cephalosporanate amidohydrolase</reactionName>
<reactionDescription> (7R)-7-(4-Carboxybutanamido)cephalosporanate + H2O <=> 7-Aminocephalosporanic acid + Glutarate</reactionDescription>
</reaction>
</reactions>
Result.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<reactions>
<reaction>
<ID>07402</ID>
<type>irreversible</type>
<substrate>15666</substrate>
<product>07756</product>
<reactionName>(7R)-7-(4-carboxybutanamido)cephalosporanate amidohydrolase</reactionName>
<reactionDescription> (7R)-7-(4-Carboxybutanamido)cephalosporanate + H2O <=> 7-Aminocephalosporanic acid + Glutarate</reactionDescription>
</reaction>
<reaction>
<ID>03063</ID>
<type>irreversible</type>
<substrate>00916</substrate>
<product>04712</product>
<reactionName>cephalosporin-C:2-oxoglutarate aminotransferase</reactionName>
<reactionDescription> Cephalosporin C + 2-Oxoglutarate <=> (7R)-7-(5-Carboxy-5-oxopentanoyl)aminocephalosporinate + D-Glutamate</reactionDescription>
</reaction>
</reactions>
Java program to do this:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.StringWriter;
import java.io.Writer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class MergeXML {
public static void main(String[] args) {
MergeXML m = new MergeXML();
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
db = dbf.newDocumentBuilder();
Document secondaryMetabolismXML = db
.parse(new File("/home/bioinfo/workspace/teste/src/file1.xml"));
Document generalMetabolismXML = db
.parse(new File("/home/bioinfo/workspace/teste/src/file2.xml"));
NodeList secondaryReactions = secondaryMetabolismXML.getElementsByTagName("reaction");
NodeList generalReactions = generalMetabolismXML.getElementsByTagName("reaction");
for (int s = 0; s < secondaryReactions.getLength(); s++) {
Node secondaryReaction = secondaryReactions.item(s);
for (int g = 0; g < generalReactions.getLength(); g++) {
Node generalReaction = generalReactions.item(g);
if (getChildrenByNodeName(secondaryReaction, "ID").getTextContent()
.equals(getChildrenByNodeName(generalReaction, "ID").getTextContent())) {
if (getChildrenByNodeName(generalReaction, "reactionName") != null) {
secondaryReaction.appendChild(secondaryMetabolismXML
.importNode(getChildrenByNodeName(generalReaction, "reactionName"), true));
}
if (getChildrenByNodeName(generalReaction, "reactionAlternativeName") != null) {
secondaryReaction.appendChild(secondaryMetabolismXML.importNode(
getChildrenByNodeName(generalReaction, "reactionAlternativeName"), true));
}
if (getChildrenByNodeName(generalReaction, "reactionDescription") != null) {
secondaryReaction.appendChild(secondaryMetabolismXML
.importNode(getChildrenByNodeName(generalReaction, "reactionDescription"), true));
}
}
}
}
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(secondaryMetabolismXML);
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
Writer output = new BufferedWriter(
new FileWriter("/home/bioinfo/workspace/teste/src/Result.xml"));
String xmlOutput = result.getWriter().toString();
output.write(xmlOutput);
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Returns a node child when you have a match with a given node name
*
* #param node
* #param nodeName
* #return
*/
public static Node getChildrenByNodeName(Node node, String nodeName) {
for (Node childNode = node.getFirstChild(); childNode != null;) {
Node nextChild = childNode.getNextSibling();
if (childNode.getNodeName().equalsIgnoreCase(nodeName)) {
return childNode;
}
childNode = nextChild;
}
return null;
}
}

Problem is, you want to append child elements to "staff" element but what you actually do is :
nodes.item(i).getParentNode().appendChild(n);
meaning you're looking for the parent node of one of the "staff" nodes of the list, and that node is "company". So you're appending a new "staff" node (the one imported from doc1) to the "company" node of doc
Now, what you want to do is to iterate over "staff" child nodes of doc1 and to append them one by one to the "staff" node of doc.
So you would want to change nodes1 definition as following :
// Retrieving child nodes of first "staff" element of doc1
NodeList nodes1 = doc1.getElementsByTagName("staff").item(0).getChildNodes();
Then change the node you append that to by replacing
nodes.item(i).getParentNode().appendChild(n);
by
nodes.item(0).appendChild(n);
So now you'll be appending all "staff" child nodes (/!\ only for the first "staff" element) of doc1 to the first "staff" element of doc
Note 1 : Dont use the iteration variable (i) you use to run through list A to select an item of another list unless you're aware of what you're doing (for example both lists are of the same length)
Note 2 : That solution will append the nodes of first "staff" element of doc1 to the first "staff" element of doc. You will maybe want to add some iterations here and there.

Related

JAVA loop through children of Nodelist

I have an XML file call it (FromThis.xml) with sample data see below:
I want to read from the file(FromThis.xml) , store the values in variable then use those variable while creating a second XML file(ToThis.xml).
Brief description of my scenario[ I will read values from XML file(FromThis.xml) first and store them in a variables. Then I will use the variables to update the second xml file which is (ToThis.xml .I later use this xml to create some JSON file in some specified format.) I have been working with this but later we need to send array of elements in (FromThis.xml). From my code below i can only get the first array element but i want to loop through the elements, store them and use it to create the second xml (ToThis.xml)
(FromThis.xml)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Root>
<ankomstDato>2020-08-20</ankomstDato>
<planlagtAntallPerUndergruppe>
<element>
<antall>67</antall>
<kode>SLAKTEGRIS</kode>
</element>
<element>
<antall>4</antall>
<kode>UNGSAU</kode>
</element>
</planlagtAntallPerUndergruppe>
</Root>
(ToThis.xml) Below xml is what i currently get.
<?xml version="1.0" encoding="UTF-8"?><map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="ankomstDato">2020-08-20</string>
<array key="planlagtAntallPerUndergruppe">
<map>
<number key="antall">67</number>
<string key="kode">SLAKTEGRIS</string>
</map>
</array>
</map>
What i would like to get as the result is
<?xml version="1.0" encoding="UTF-8"?><map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="ankomstDato">2020-08-20</string>
<array key="planlagtAntallPerUndergruppe">
<map>
<number key="antall">67</number>
<string key="kode">SLAKTEGRIS</string>
</map>
<map>
<number key="antall">4</number>
<string key="kode">UNGSAU</string>
</map>
</array>
</map>
Below is my Code
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.w3c.dom.Element;
//** */
public class SolutionXML2XmlFormat {
//Create Public Variables to store data
//**
public static String ankomstDato_value; //1
public static String[] planlagtAntallPerUndergruppe_antall_value = new String[6]; //
public static String[] planlagtAntallPerUndergruppe_kode_value = new String[6]; //
//+++
public void Xml2JavaObject(String FromThis){
//read the xml(TheXMLPath) and store values in variables
// Boolean and numbers should be having values for string use " " if empty
try {
File file = new File(FromThis);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(file);
document.getDocumentElement().normalize();
System.out.println("Root element :" + document.getDocumentElement().getNodeName());
System.out.println("------------------------ \n");
//1 . ankomstDato
String ankomstDato = document.getElementsByTagName("ankomstDato").item(0).getTextContent();
ankomstDato_value = ankomstDato;
//end ankomstDato
NodeList planlagtAntallPerUndergruppe= document.getElementsByTagName("planlagtAntallPerUndergruppe");
for (int temp = 0; temp < planlagtAntallPerUndergruppe.getLength(); temp++) {
Node nNode = planlagtAntallPerUndergruppe.item(temp);
System.out.println("\n Current Elements :" + planlagtAntallPerUndergruppe.getLength());
System.out.println("\n No. of Element :" + temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
String element18 = eElement.getElementsByTagName("antall").item(0).getTextContent();
planlagtAntallPerUndergruppe_antall_value[temp] = element18;
String element19 = eElement.getElementsByTagName("kode").item(0).getTextContent();
planlagtAntallPerUndergruppe_kode_value[temp] = element19;
}
}
} catch (Exception e) {
e.printStackTrace();
}
//Call method to write values
Write2XMLfile();
}
public void Write2XMLfile(){
XPathFactory xpathFact = XPathFactory.newInstance();
XPath xpath = xpathFact.newXPath();
try {
//
String filepath = "E:/utils/Tothis.xml";
//
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
// 1. ankomstDato
Node ankomstDato = (Node) xpath.evaluate("(/map/string[#key='ankomstDato'])[1]", doc, XPathConstants.NODE);
ankomstDato.setTextContent(ankomstDato_value );
// End ankomstDato
//2. planlagtAntallPerUndergruppe **************************
System.out.println("\n This is second" );
Node planlagtAntallPerUndergruppe = (Node) xpath.evaluate("/map/array[#key='planlagtAntallPerUndergruppe']/*", doc, XPathConstants.NODE);
if(null != planlagtAntallPerUndergruppe) {
NodeList nodeList = planlagtAntallPerUndergruppe.getChildNodes();
for (int i = 0;null!=nodeList && i < nodeList.getLength(); i++) {
Node nod = nodeList.item(i);
//System.out.println("\n");
if(nod.getNodeType() == Node.ELEMENT_NODE){
NodeList arrayElements_18 = (NodeList) xpath.evaluate("/map/array[#key='planlagtAntallPerUndergruppe']/*", doc, XPathConstants.NODESET);
//System.out.println("\n number of elements" + arrayElements_18.getLength());
for (int j = 0; j < arrayElements_18.getLength(); j++) {
//. antall
Node antall = (Node) xpath.evaluate("(/map/array/map/number[#key='antall'])[1]", doc, XPathConstants.NODE);
antall.setTextContent(planlagtAntallPerUndergruppe_antall_value[j]);
// end antall
//. kode
Node kode = (Node) xpath.evaluate("(/map/array/map/string[#key='kode'])[1]", doc, XPathConstants.NODE);
kode.setTextContent(planlagtAntallPerUndergruppe_kode_value[j]);
//System.out.println("\n\n antall: " + planlagtAntallPerUndergruppe_antall_value[j]);
// end kode
}
}
}
}
// end array planlagtAntallPerUndergruppe
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filepath));
transformer.transform(source, result);
System.out.println("Done Updating The Api_XML_Format.xml");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SAXException sae) {
sae.printStackTrace();
} catch (XPathExpressionException xee) {
xee.printStackTrace();
}
}
}
as per the given code, planlagtAntallPerUndergruppe NodeList size is a one. because you select the <planlagtAntallPerUndergruppe> element.
NodeList planlagtAntallPerUndergruppe = document.getElementsByTagName("planlagtAntallPerUndergruppe");
hence, in the for loop, declared arrays collect the first <element> values only from FromThis.xml file.
<element>
<antall>67</antall>
<kode>SLAKTEGRIS</kode>
</element>
Solution
get the <element> NodeList into planlagtAntallPerUndergruppe as follows,
NodeList planlagtAntallPerUndergruppe = document.getElementsByTagName("element");

Root element shouldn't be repeat and, the child nodes only needed to be appended in XML Dom Parser

After form submission, the values are to be stored in an XML file. (XML Dom PArser)
Below given the program which I tried to do the same.
public void writeXMLfile(ApplyLieuDto lieuDto) {
String satDte =
Util.convertUtilDateToString(lieuDto.getSatDutyDteUtil());
//String satDteAMPM = lieuDto.getSatDutyDteAmPm();
//String satDutyDte = satDte + satDteAMPM;
String offDte = Util.convertUtilDateToString(lieuDto.getOffDteUtil());
//String offDteAMPM = lieuDto.getOffDteAmPm();
//String offDate = offDte + offDteAMPM;
String modDate =
Util.convertUtilDateToString(lieuDto.getDateUpdateUtil());
String filePath = "file.xml";
try {
DocumentBuilderFactory docFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("lieu");
doc.appendChild(rootElement);
// staff elements
Element staff = doc.createElement("staff");
rootElement.appendChild(staff);
// set attribute to staff element
Attr attr = doc.createAttribute("id");
attr.setValue(lieuDto.getStaffId());
staff.setAttributeNode(attr);
// name elements
Element firstname = doc.createElement("name");
firstname.appendChild(doc.createTextNode(lieuDto.getName()));
staff.appendChild(firstname);
// contact number elements
Element contact = doc.createElement("contactnumber");
contact.appendChild(doc.createTextNode(lieuDto.getContact()));
staff.appendChild(contact);
// email elements
Element email = doc.createElement("email");
email.appendChild(doc.createTextNode(lieuDto.getEmail()));
staff.appendChild(email);
// satdutydate elements
Element satDutyDate = doc.createElement("satDte");
satDutyDate.appendChild(doc.createTextNode(satDte));
staff.appendChild(satDutyDate);
// satdutydateAMPM elements
Element satDutyDateAMPM = doc.createElement("satDteAMPM");
satDutyDateAMPM.appendChild(doc.createTextNode
(lieuDto.getSatDutyDteAmPm()));
staff.appendChild(satDutyDateAMPM);
// offDate elements
Element offDat = doc.createElement("offdate");
offDat.appendChild(doc.createTextNode(offDte));
staff.appendChild(offDat);
// offDateAMPM elements
Element offDatAMPM = doc.createElement("offdateAMPM");
offDatAMPM.appendChild(doc.createTextNode(lieuDto.getOffDteAmPm()));
staff.appendChild(offDatAMPM);
// appOfficer elements
Element appOfficer = doc.createElement("approvingofficer");
appOfficer.appendChild(doc.createTextNode
(lieuDto.getApprovingOfficer()));
staff.appendChild(appOfficer);
// Date elements
Element modifieddate = doc.createElement("modifieddate");
modifieddate.appendChild(doc.createTextNode(modDate));
staff.appendChild(modifieddate);
// status elements
Element status = doc.createElement("status");
status.appendChild(doc.createTextNode(lieuDto.getStatus()));
staff.appendChild(status);
// write the content into xml file
TransformerFactory transformerFactory =
TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new
FileWriter(filePath,true));
// Output to console for testing
StreamResult strmResult = new StreamResult(System.out);
transformer.transform(source, result);
transformer.transform(source, strmResult);
System.out.println("File saved!");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The output I got as something like this below
<company>
<staff id="1">
<firstname>Priya</firstname>
<lastname>Rajan</lastname>
<salary>100000</salary>
</staff>
</company>
<company>
<staff id="2">
<firstname>Peter</firstname>
<lastname>Jas</lastname>
<salary>100000</salary>
</staff>
</company>
But, the expected result is
<company>
<staff id="1">
<firstname>Priya</firstname>
<lastname>Rajan</lastname>
<salary>100000</salary>
</staff>
<staff id="2">
<firstname>Peter</firstname>
<lastname>Jas</lastname>
<salary>100000</salary>
</staff>
</company>
Root element shouldn't be repeat and, the child nodes only needed to be appended.
Please help me on this.
Thanks.
I got the answer. `
public boolean writeXMLfile(ApplyLieuDto lieuDto)
{
boolean isAdded = false;
String filePath = "file.xml";
DocumentBuilderFactory documentBuilderFactory =
DocumentBuilderFactory.newInstance();
try {
DocumentBuilder documentBuilder =
documentBuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(filePath);
NodeList oldList = doc.getElementsByTagName("staff");
int oldListCount = oldList.getLength();
System.out.println("Old List Count Value :: "+oldListCount);
Element root = doc.getDocumentElement();
Element rootElement = doc.getDocumentElement();
Collection<ApplyLieuDto> svr = new ArrayList<ApplyLieuDto>();
svr.add(lieuDto);
for(ApplyLieuDto lieu : svr)
{
Element staff = doc.createElement("staff");
rootElement.appendChild(staff);
// set attribute to staff element
Attr attr = doc.createAttribute("id");
attr.setValue(lieu.getStaffId());
staff.setAttributeNode(attr);
Element firstname = doc.createElement("name");
firstname.appendChild(doc.createTextNode(lieu.getName()));
staff.appendChild(firstname);
// contact number elements
Element contact = doc.createElement("contactnumber");
contact.appendChild(doc.createTextNode(lieu.getContact()));
staff.appendChild(contact);
// email elements
Element email = doc.createElement("email");
email.appendChild(doc.createTextNode(lieu.getEmail()));
staff.appendChild(email);
String satDte = Util.convertUtilDateToString(lieu.getSatDutyDteUtil());
// satdutydate elements
Element satDutyDate = doc.createElement("satDte");
satDutyDate.appendChild(doc.createTextNode(satDte));
staff.appendChild(satDutyDate);
// satdutydateAMPM elements
Element satDutyDateAMPM = doc.createElement("satDteAMPM");
satDutyDateAMPM.appendChild(doc.createTextNode(lieu.getSatDutyDteAmPm()));
staff.appendChild(satDutyDateAMPM);
String offDte = Util.convertUtilDateToString(lieu.getOffDteUtil());
// offDate elements
Element offDat = doc.createElement("offdate");
offDat.appendChild(doc.createTextNode(offDte));
staff.appendChild(offDat);
// offDateAMPM elements
Element offDatAMPM = doc.createElement("offdateAMPM");
offDatAMPM.appendChild(doc.createTextNode(lieu.getOffDteAmPm()));
staff.appendChild(offDatAMPM);
// appOfficer elements
Element appOfficer = doc.createElement("approvingofficer");
appOfficer.appendChild(doc.createTextNode(lieu.getApprovingOfficer()));
staff.appendChild(appOfficer);
String modDate = Util.convertUtilDateToString(lieu.getDateUpdateUtil());
// Date elements
Element modifieddate = doc.createElement("modifieddate");
modifieddate.appendChild(doc.createTextNode(modDate));
staff.appendChild(modifieddate);
// status elements
Element status = doc.createElement("status");
status.appendChild(doc.createTextNode(lieu.getStatus()));
staff.appendChild(status);
root.appendChild(staff);
}
DOMSource source = new DOMSource(doc);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
StreamResult result = new StreamResult(filePath);
StreamResult strmResult = new StreamResult(System.out);
transformer.transform(source, result);
transformer.transform(source, strmResult);
NodeList newList = doc.getElementsByTagName("staff");
int newListCount = newList.getLength();
System.out.println("New List Count Value :: "+newListCount);
if(newListCount > oldListCount)
{
isAdded = true;
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
return isAdded;
}
`

Java - Writing to XML file indents everything except the first element

Using JAVA, I am trying, after having opened a .xml file, to append the creation of a new node using a SWING Application. Every new node gets entered correctly EXCEPT the first element which always get stuck at the far left of the file, with no identation.
schedule.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Schedule>
<Lesson>
<Title>Artificial Intelligence</Title>
<Lecture>
<Day>Thursday</Day>
</Lecture>
<Professor>John Doe</Professor>
</Lesson>
<Lesson>
<Title>Constraint Satisfaction Problems</Title>
<Lecture>
<Day>Monday</Day>
</Lecture>
</Lesson>
</Schedule>
My attempt to write to the file :
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse("schedule.xml");
Element root = document.getDocumentElement();
Element newLesson = document.createElement("Lesson");
Element newTitle = document.createElement("Title");
newTitle.appendChild(document.createTextNode("myLesson"));
newLesson.appendChild(newTitle);
Element newLecture = document.createElement("Lecture");
newLesson.appendChild(newLecture);
Element newDay = document.createElement("Day");
newDay.appendChild(document.createTextNode("myDay"));
newLecture.appendChild(newDay);
Element newProfessor = document.createElement("Professor");
newProfessor.appendChild(document.createTextNode("myProfessor"));
newLesson.appendChild(newProfessor);
root.appendChild(newLesson);
DOMSource source = new DOMSource(document);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
StreamResult result = new StreamResult("schedule.xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "8");
transformer.transform(source, result);
} catch (Exception e) {
e.printStackTrace();
}
Output
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Schedule>
<Lesson>
<Title>Artificial Intelligence</Title>
<Lecture>
<Day>Thursday</Day>
</Lecture>
<Professor>John Doe</Professor>
</Lesson>
<Lesson>
<Title>Constraint Satisfaction Problems</Title>
<Lecture>
<Day>Monday</Day>
</Lecture>
</Lesson>
<Lesson>
<Title>myLesson</Title>
<Lecture>
<Day>myDay</Day>
</Lecture>
<Professor>myProfessor</Professor>
</Lesson>
</Schedule>
Solution: used a function for space trimming from here
Function:
private static void removeEmptyText(Node node){
Node child = node.getFirstChild();
while(child!=null){
Node sibling = child.getNextSibling();
if(child.getNodeType()==Node.TEXT_NODE){
if(child.getTextContent().trim().isEmpty())
node.removeChild(child);
}else
removeEmptyText(child);
child = sibling;
}
}

Merging 2 XML files looping on NodeList

I have 2 xml files .. to e merged in 1 xml file
input files:
reference.xml
<company>
<staff>
<name>
<surname>smith </surname>
</name>
<phone>465456433</phone>
<email>gmail1</email>
</staff>
</company>
comparison.xml
<company>
<staff>
<name>
<initials>js</initials>
</name>
<area>area1</area>
<city>city1</city>
</staff>
</company>
expected output:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<company>
<staff>
<name>
<surname>smith</surname>
<initials>js</initials>
</name>
<phone>465456433</phone>
<email>gmail1</email>
<area>area1</area>
<city>city1</city>
</staff>
</company>
I get that output with a hardcoded code by getting tag names.. But is there a way to loop over each parent node and import its children from the 2 files without naming tags to be GENERIC
public class merge {
public static void main(String[] args) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
Document doc = null;
Document doc2 = null;
try {
///////////////////////////////////////////////////////////////////////
db = dbf.newDocumentBuilder();
doc = db.parse(new File("C:/Users/IBM_ADMIN/Desktop/reference.xml"));
doc2 = db.parse(new File("C:/Users/IBM_ADMIN/Desktop/comparison.xml"));
NodeList ndListFirstFile = doc.getElementsByTagName("staff");
Node nodeArea = doc.importNode(doc2.getElementsByTagName("area").item(0), true);
Node nodeCity = doc.importNode(doc2.getElementsByTagName("city").item(0), true);
ndListFirstFile.item(0).appendChild(nodeArea);
ndListFirstFile.item(0).appendChild(nodeCity);
NodeList ndList = doc.getElementsByTagName("name");
Node nodesur = doc.importNode(doc.getElementsByTagName("surname").item(0), true);
Node nodein = doc.importNode(doc2.getElementsByTagName("initials").item(0), true);
ndList.item(0).appendChild(nodesur);
ndList.item(0).appendChild(nodein);
///////////////////////////////////////////////////////////////////
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
Writer output = new BufferedWriter(new FileWriter("C:/Users/IBM_ADMIN/Desktop/final.xml"));
String xmlOutput = result.getWriter().toString();
output.write(xmlOutput);
output.close();
} 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 (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Thanks
You can use
NodeList list = doc.getChildNodes();
But then you have to check each child to verify it is an element.
for (int i = 0; i < list.getLength(); ++i)
{
Node n = list.item(i);
if (n.getType().equals(Node.ELEMENT_NODE))
{
n.getNodeName();
}
}
Something like that. To handle all elements in a document you have to use a Breadth/Depth First algorithm.
Stack<Node> pending = new Stack<Node>();
pending.push(doc.getChildNodes().item(0));
while(!pending.empty())
{
Node n = pending.pop();
n.getChildNodes();
...
}
It should be clear how to move on from here. If not I will work out a more working version when I have time.

Java read XML and put textnodes into an array of strings?

I apologize if this question has been asked somewhere, I've been searching on google for over an hour and can't seem to figure out how to do this.
I've created a config file for an application I'm making which is stored in XML and I've gotten the application to successfully create the XML file if it doesn't exist using DOM,
(code,in case it's needed)
public static void newConfig() {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root element
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("settings");
doc.appendChild(rootElement);
// address element
Element address = doc.createElement("address");
address.appendChild(doc.createTextNode("127.0.0.1"));
rootElement.appendChild(address);
// port element
Element port = doc.createElement("port");
port.appendChild(doc.createTextNode("3306"));
rootElement.appendChild(port);
// user element
Element user = doc.createElement("user");
user.appendChild(doc.createTextNode("user"));
rootElement.appendChild(address);
// password element
Element pass = doc.createElement("pass");
pass.appendChild(doc.createTextNode("password"));
rootElement.appendChild(pass);
// database element
Element datab = doc.createElement("database");
datab.appendChild(doc.createTextNode("A1"));
rootElement.appendChild(datab);
// write the content to XML
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("config.xml"));
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(source, result);
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
which creates this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<settings>
<port>3306</port>
<address>127.0.0.1</address>
<pass>password</pass>
<database>A1</database>
</settings>
how would I go about retrieving those textnodes as an array of strings?
try this
NodeList nodes = docBuilder.parse(new File("1.xml")).getDocumentElement().getChildNodes();
String[] a = new String[4];
for (int i = 0, j = 0; i < nodes.getLength(); i++) {
Node n = nodes.item(i);
if (n instanceof Element) {
a[j++] = n.getTextContent().trim();
}
}

Categories