How to add an attribute to the root node - java

I have an xml as String
<color>
<name>black</name>
<color>
I want to add an attribute to root node and save a xml as String again.
<color id="1">
<name>black</name>
<color>
But I can't. Here is my code
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.xml.sax.InputSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
String xml = "<color><name>black</name></color>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
Document document = builder.parse(is);
Element element = (Element) document.getFirstChild();
element.setAttribute("id", "1");
String result = document.toString();
System.out.println(result);
The output is [#document: null]. Help me please resolve my problem

You can not use document.toString() to get output. You need to convert document object back to xml string.
Please check following code. It will help to solve your problem.
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
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 org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class test1 {
public static void main(String[] args) throws SAXException, IOException,
ParserConfigurationException {
final String xmlStr = "<color><name>black</name></color>";
Document doc = convertStringToDocument(xmlStr);
String str = convertDocumentToString(doc);
System.out.println(str);
}
private static Document convertStringToDocument(String xmlStr)
throws SAXException, IOException, ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xmlStr));
Document document = builder.parse(is);
Element element = (Element) document.getFirstChild();
element.setAttribute("id", "1");
String result = document.toString();
System.out.println(result);
return document;
}
private static String convertDocumentToString(Document doc) {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer;
try {
transformer = tf.newTransformer();
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(doc), new StreamResult(writer));
String output = writer.getBuffer().toString();
return output;
} catch (TransformerException e) {
e.printStackTrace();
}
return null;
}
}

Related

Updating an XML in Java

I am trying to change the PlannedDuration of Activity A04 but I have not been able to see the changes in the XML file. The changes are not updated into the file. I do not know what I am doing wrong.
The XML is too long. The file has information about several activities. I am interested only in the activity with Id A04.
The initial value of the PlannedDuration is 16 and I changed it to 25.
XML File:
package modifyXML;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
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 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 ModifyXML{
public static void main(String[] args) {
File xmlfile = new File("C:/Users/dianitaf/Downloads/xml Files/CS_1.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
try {
dBuilder = dbFactory.newDocumentBuilder();
Document document = dBuilder.parse(xmlfile);
document.getDocumentElement().normalize();
updateElementValue(document,"Id", "A04");
document.getDocumentElement().normalize();
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File("xmlfile"));
transformer.transform(source, result);
System.out.println("XML file updated successfully");
} catch (SAXException | ParserConfigurationException | IOException | TransformerException e1) {
e1.printStackTrace();
}
}
private static void updateElementValue(Document document, String textNodeName, String textNodeValue) {
NodeList Activity = document.getElementsByTagName("Activity");
Element act = null;
//loop for each activity
for(int i=0; i<Activity.getLength();i++){
Node activityNode = Activity.item(i);
if(activityNode.getNodeType() == Node.ELEMENT_NODE)
{
Element activityElement = (Element) activityNode;
NodeList textNodes = activityElement.getElementsByTagName(textNodeName);
if(textNodes.getLength() > 0)
{
if(textNodes.item(0).getTextContent().equalsIgnoreCase(textNodeValue))
{
System.out.println(textNodes.item(0).getTextContent());
System.out.println(activityElement.getElementsByTagName("Name").item(0).getTextContent());
act = (Element) Activity.item(i);
Node duration = act.getElementsByTagName("PlannedDuration").item(0).getFirstChild();
System.out.println("Initial Duration : " + act.getElementsByTagName("PlannedDuration").item(0).getTextContent()); act.getElementsByTagName("PlannedDuration").item(0).getTextContent();
duration.setTextContent("25");
System.out.println("Updaded Duration : " + act.getElementsByTagName("PlannedDuration").item(0).getTextContent());
}
}
}
}
}
}
XML:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><APIBusinessObjects>
<ProjectList>
<Project ObjectId="4627">
<Id>CS_1</Id>
<Name>Case Study No.1 Warehouse Project - CPM</Name>
</Project>
</ProjectList>
<Project>
<Activity>
<Id>A04</Id>
<Name>Nailers to Purlins</Name>
<PlannedDuration>16</PlannedDuration>
<StartDate>2018-12-26Te8:00:00</StartDate>
</Activity>
</Project>
</APIBusinessObjects>
Java:
package modifyXML;
import java.io.File;
import java.io.IOException;
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 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 ModifyXML {
public static void main(String[] args) {
File xmlfile = new File("D:\\delete\\test.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
try {
dBuilder = dbFactory.newDocumentBuilder();
Document document = dBuilder.parse(xmlfile);
document.getDocumentElement().normalize();
updateElementValue(document, "Id", "A04");
document.getDocumentElement().normalize();
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(xmlfile);
transformer.transform(source, result);
System.out.println("XML file updated successfully");
} catch (SAXException | ParserConfigurationException | IOException | TransformerException e1) {
e1.printStackTrace();
}
}
private static void updateElementValue(Document document, String textNodeName, String textNodeValue) {
NodeList Activity = document.getElementsByTagName("Activity");
Element act = null;
// loop for each activity
for (int i = 0; i < Activity.getLength(); i++) {
Node activityNode = Activity.item(i);
if (activityNode.getNodeType() == Node.ELEMENT_NODE) {
Element activityElement = (Element) activityNode;
NodeList textNodes = activityElement.getElementsByTagName(textNodeName);
if (textNodes.getLength() > 0) {
if (textNodes.item(0).getTextContent().equalsIgnoreCase(textNodeValue)) {
System.out.println(textNodes.item(0).getTextContent());
System.out.println(activityElement.getElementsByTagName("Name").item(0).getTextContent());
act = (Element) Activity.item(i);
Node duration = act.getElementsByTagName("PlannedDuration").item(0).getFirstChild();
System.out.println("Initial Duration : "
+ act.getElementsByTagName("PlannedDuration").item(0).getTextContent());
act.getElementsByTagName("PlannedDuration").item(0).getTextContent();
duration.setTextContent("25");
System.out.println("Updaded Duration : "
+ act.getElementsByTagName("PlannedDuration").item(0).getTextContent());
}
}
}
}
}
}

Read from folder and update the XML tag value

I have a folder("Container") inside this i have some .txt files which actually contains XML. All files have a common element <Number> which i want to increment by 1 for all the XML files.
any help.
i have done the change for a single .txt file, which is okay:-
package ParsingXML;
import java.io.File;
import java.io.IOException;
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 org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
public class ReadAndModifyXMLFile {
public static final String xmlFilePath = "C:\\Users\\PSINGH17\\Desktop\\testFile.txt";
public static void main(String argv[]) {
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(xmlFilePath);
// Get employee by tag name
//use item(0) to get the first node with tag name "employee"
Node employee = document.getElementsByTagName("employee").item(0);
// update employee , increment the number
NamedNodeMap attribute = employee.getAttributes();
Node nodeAttr = attribute.getNamedItem("number");
String str= nodeAttr.getNodeValue();
System.out.println(str);
int val= Integer.parseInt(str);
System.out.println(val);
val=val+1;
System.out.println(val);
String final_value= String.valueOf(val);
System.out.println(final_value);
nodeAttr.setTextContent(final_value);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(new File(xmlFilePath));
transformer.transform(domSource, streamResult);
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SAXException sae) {
sae.printStackTrace();
}
}
}
xml file:-
<?xml version="1.0" encoding="UTF-8" standalone="no"?><company>
<employee number="14">
<firstname>Pranav</firstname>
<lastname>Singh</lastname>
<email>pranav#example.org</email>
<salary>1000</salary>
</employee>
</company>
So this code uses the initial value digits after hash to start the counter.
Then it iterates through all the files in the folder.
The first file will get the initial value, the rest will get incremented values.
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
public class TestFile {
public static final String xmlFileFolder = "C:\\Rahul\\test";
private static final String initialValue = "450-000-1212";
public static void main(String argv[]) {
int baseValue = Integer.parseInt(getValueAfterLastDash(initialValue));
System.out.println("startValue " + baseValue);
File folder = new File(xmlFileFolder);
for (File file : folder.listFiles()) {
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(file);
Node employee = document.getElementsByTagName("employee").item(0);
NamedNodeMap attribute = employee.getAttributes();
Node nodeAttr = attribute.getNamedItem("number");
System.out.println(getValueBeforeLastDash(initialValue) + baseValue);
nodeAttr.setTextContent(getValueBeforeLastDash(initialValue) + baseValue);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(file);
transformer.transform(domSource, streamResult);
baseValue++;
} catch (Exception ignored) {
}
}
}
private static String getValueAfterLastDash(String initialValue) {
return initialValue.substring(initialValue.lastIndexOf('-') + 1, initialValue.length());
}
private static String getValueBeforeLastDash(String initialValue) {
return initialValue.substring(0, initialValue.lastIndexOf('-') + 1);
}
}

How to write Multiple Element in the XML using JAVA

Sample XML which i have to generate using JAVA
sense
168
192.168.140.150
002EC0FEFF83EA97
Code Used I have written so far
import java.io.File;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
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 org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class SampleCode {
public static final String xmlFilePath = "C:\\Users\\harsh.sharma\\Desktop\\Sense Performance\\Generated\\xmlfile.xml";
public static void main(String[] args) throws ParseException {
// TODO Auto-generated method stub
try {
String cid_Value="168";
String ip_Value="192.168.140.150";
String id_Value="002EC0FEFF83EA97";
String sensorsid_Value="002EC0FEFF8FFF27";
String desc_Value=" ";
String batt_Value="6.60";
String sig_Value="-55";
String scount_Value="0";
String rdate_Value="15/05/2015 21:47:04";
DateFormat dateFormat = new SimpleDateFormat("dd/MM/YYYY HH:mm:ss");
//get current date time with Date()
#SuppressWarnings("deprecation")
Calendar cal = Calendar.getInstance();
String mdate_Value=dateFormat.format(cal.getTime());
DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
//root element
Element root = document.createElement("msgs");
document.appendChild(root);
//msg element
Element msg = document.createElement("msg");
root.appendChild(msg);
//type element
Element type = document.createElement("type");
msg.appendChild(type);
type.setTextContent("Sense");
//cid element
Element cid = document.createElement("cid");
msg.appendChild(cid);
cid.setTextContent(cid_Value);
//ip element
Element ip = document.createElement("ip");
msg.appendChild(ip);
ip.setTextContent(ip_Value);
Element errs = document.createElement("errs");
msg.appendChild(errs);
//id element
Element id = document.createElement("id");
msg.appendChild(id);
id.setTextContent(id_Value);
//sensors element
Element sensors = document.createElement("sensors");
msg.appendChild(sensors);
//Sensor element
Element sensor = document.createElement("sensor");
//sensors.appendChild(sensor);
sensor.setAttribute("sensorsid",sensorsid_Value);
sensor.setAttribute("desc",desc_Value);
sensor.setAttribute("batt",batt_Value);
sensor.setAttribute("sig", sig_Value);
sensor.setAttribute("scount",scount_Value);
sensor.setAttribute("rdate",rdate_Value);
sensor.setAttribute("mdate",mdate_Value);
sensors.appendChild(sensor);
// create the xml file
//transform the DOM Object to an XML File
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(new File(xmlFilePath));
// If you use
// StreamResult result = new StreamResult(System.out);
// the output will be pushed to the standard output ...
// You can use that for debugging
transformer.transform(domSource, streamResult);
System.out.println("Done creating XML File");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
}
I want it should give me multiple rows under the sensor Element, I want to write the loop that I can generate multiple data for the sensor Element

splitting xml ino mutiple xmls based on xml tags using java

i need to split my xml into multiple xml based on the tag start and close. For this i tried with the following code
public class XmlSplit {
public static void main(String [] args) throws Exception {
File input = new File("/home/dev702/Desktop/cadgraf-test/Data_Entry.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = (Document) dbf.newDocumentBuilder().parse(input);
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("//Data_x0020_Entry", doc, XPathConstants.NODESET);
int itemsPerFile = 500;
int fileNumber = 0;
Document currentDoc = (Document) dbf.newDocumentBuilder().newDocument();
Node rootNode;
rootNode = currentDoc.createElement("Data_x0020_Entry");
File currentFile = new File(fileNumber+".xml");
for (int i=1; i <= nodes.getLength(); i++) {
Node imported = currentDoc.importNode(nodes.item(i-1), true);
rootNode.appendChild(imported);
if (i % itemsPerFile == 0) {
writeToFile(rootNode, currentFile);
rootNode = currentDoc.createElement("Data_x0020_Entry");
currentFile = new File((++fileNumber)+".xml");
}
}
writeToFile(rootNode, currentFile);
}
private static void writeToFile(Node node, File file) throws Exception {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(node), new StreamResult(new FileWriter(file)));
}
}
In this am getting error on currentDoc.createElement. Am not able to compile this code and it is saying createElement not available.
Sample xml file
<?xml version="1.0" encoding="UTF-8"?>
<dataroot
xmlns:od="urn:schemas-microsoft-com:officedata"
xmlns:xsi="w3.org/2001/XMLSchema-instance" ;
xsi:noNamespaceSchemaLocation="Data%20Entry.xsd"
generated="2014-02-12T14:35:47"
>
<Data_x0020_Entry>
<ID>1004</ID>
<User>006Parthiban</User>
<Data_x0020_Entry_x0020_Date>2013-12-26T00:00:00</Data_x0020_Entry_x0020_Date>
<Publication>Daily Thanthi</Publication>
<Edition>CE City Edition</Edition>
<Location>Bangalore</Location>
</Data_x0020_Entry>
</dataroot>
I could not see any compilation issue in this code. Please check your import statements and verify that you have imported proper classes. the list of classes which I import are as below
import java.io.File;
import java.io.FileWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
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.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
i think u have imported import javax.swing.text.Document; change that to import org.w3c.dom.Document;
And if ur using Swing too than use fully qualified that for to create Document
like
org.w3c.dom.Document currentDoc = (org.w3c.dom.Document) dbf.newDocumentBuilder().newDocument();
Update
I think the root element should be "dataroot" for splitted xmls. and you need to change your code to generate correct number of xml files (look at below code)..look at the code below..i tested for
int itemsPerFile = 2; ..it is working fine..
NOTE remove ";" from input xml file after namespcae
import java.io.File;
import java.io.FileWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
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.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XmlSplit {
public static void main(String [] args) throws Exception {
File input = new File("src/test.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = (Document) dbf.newDocumentBuilder().parse(input);
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("//Data_x0020_Entry", doc, XPathConstants.NODESET);
int itemsPerFile = 2;
int fileNumber = 0;
Document currentDoc = (Document) dbf.newDocumentBuilder().newDocument();
Node rootNode;
rootNode = currentDoc.createElement("dataroot");
File currentFile = new File(fileNumber+".xml");
for (int i=1; i <= nodes.getLength(); i++) {
Node imported = currentDoc.importNode(nodes.item(i-1), true);
rootNode.appendChild(imported);
if (i % itemsPerFile == 0) {
writeToFile(rootNode, currentFile);
rootNode = currentDoc.createElement("dataroot");
currentFile = new File((++fileNumber)+".xml");
}
else
{
writeToFile(rootNode, currentFile);
}
}
}
private static void writeToFile(Node node, File file) throws Exception {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(node), new StreamResult(new FileWriter(file)));
}
}
let me know if u face any issues :)

JAVA XML PARSING TO SPLIT XML based on object and class tag elements

This is the JAVA XML i'm parsing..
<objects>
<object>...<class>A /<class>...</object>
<object>...<class>B</class>....</object>
<object>...<class>A /<class>...</object>
</objects>
Now i split the XML into 3 XML's based on object tag with the below code.
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse("xml");
doc.getDocumentElement().normalize();
TransformerFactory tranFactory = TransformerFactory.newInstance();
Transformer aTransformer = tranFactory.newTransformer();
NodeList list =(NodeList) doc.getElementsByTagName("object");
System.out.println("XML SPLITED");
for (int i=0; i<list.getLength(); i++){
Node element = list.item(i).cloneNode(true);
if(element.hasChildNodes()){
Source src = new DOMSource(element);
FileOutputStream fs=new FileOutputStream("XML" + i + ".xml");
Result dest = new StreamResult(fs);
aTransformer.transform(src, dest);
fs.close();
}
My requirement is to get only the files with class tag A.So my output will be only 2 XML's.Please post your answers.
Using your example, you can do that this way:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
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.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XmlSplitting {
private static final Logger logger = Logger.getLogger(XmlSplitting.class.getName());
private static final String FILE_PATH = "./";
private DocumentBuilder builder;
private Transformer transformer;
public XmlSplitting() throws ParserConfigurationException, TransformerConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
this.builder = factory.newDocumentBuilder();
TransformerFactory transfromerFactory = TransformerFactory.newInstance();
this.transformer = transfromerFactory.newTransformer();
}
public static void main(String[] args) {
try {
XmlSplitting s = new XmlSplitting();
s.run();
} catch (ParserConfigurationException | SAXException | IOException | TransformerException x) {
logger.log(Level.SEVERE, "Error", x);
}
}
private void run() throws ParserConfigurationException, SAXException, IOException, TransformerException {
File file = new File(FILE_PATH + "xml.xml");
if (file.exists()) {
Document document = this.builder.parse(file);
document.normalize();
NodeList list = document.getElementsByTagName("object");
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
Element object = (Element)node;
NodeList classes = object.getElementsByTagName("class");
if (1 == classes.getLength()) {
Node clazz = classes.item(0);
if (Node.ELEMENT_NODE == clazz.getNodeType()) {
this.copyNodeToNewFile(clazz.getTextContent(), node, i);
}
} else {
logger.log(Level.SEVERE, "Number of class nodes in node object is different than expected. Number of class nodes found: {0}.", classes.getLength());
}
}
}
} else {
logger.log(Level.SEVERE, "You provided wrong path for xml file.");
}
}
private void copyNodeToNewFile(String content, Node node, int i) throws IOException, TransformerException {
boolean copy = this.nodeShouldBeCopied(content);
logger.log(Level.INFO, "Node with content {0} will {1}be moved to separete file.", new Object[]{content, true == copy ? "" : "not "});
if (copy) {
String fileName = String.format("%sxml%d.xml", FILE_PATH, i);
try (FileOutputStream fos = new FileOutputStream(fileName)) {
Source source = new DOMSource(node);
Result destination = new StreamResult(fos);
this.transformer.transform(source, destination);
}
}
}
// here you can change condition to copy given node to file
private boolean nodeShouldBeCopied(String content) {
return content.contains("A");
}
}
How about using a Brazilian framework to parse your XML? it will make your code more exotic and you can tell your friends about it:
http://jcoltrane.sourceforge.net/userguide/extending_parsing_process.html

Categories