Create Xml File Using Java

How to create XML file with specific structure in Java

You can use the JDOM library in Java.
Define your tags as Element objects, document your elements with Document Class, and build your xml file with SAXBuilder. Try this example:

//Root Element
Element root=new Element("CONFIGURATION");
Document doc=new Document();
//Element 1
Element child1=new Element("BROWSER");
//Element 1 Content
child1.addContent("chrome");
//Element 2
Element child2=new Element("BASE");
//Element 2 Content
child2.addContent("http:fut");
//Element 3
Element child3=new Element("EMPLOYEE");
//Element 3 --> In this case this element has another element with Content
child3.addContent(new Element("EMP_NAME").addContent("Anhorn, Irene"));

//Add it in the root Element
root.addContent(child1);
root.addContent(child2);
root.addContent(child3);
//Define root element like root
doc.setRootElement(root);
//Create the XML
XMLOutputter outter=new XMLOutputter();
outter.setFormat(Format.getPrettyFormat());
outter.output(doc, new FileWriter(new File("myxml.xml")));

Create XML file using java

You can use a DOM XML parser to create an XML file using Java. A good example can be found on this site:

try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

//root elements
Document doc = docBuilder.newDocument();

Element rootElement = doc.createElement("company");
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("1");
staff.setAttributeNode(attr);

//shorten way
//staff.setAttribute("id", "1");

//firstname elements
Element firstname = doc.createElement("firstname");
firstname.appendChild(doc.createTextNode("yong"));
staff.appendChild(firstname);

//lastname elements
Element lastname = doc.createElement("lastname");
lastname.appendChild(doc.createTextNode("mook kim"));
staff.appendChild(lastname);

//nickname elements
Element nickname = doc.createElement("nickname");
nickname.appendChild(doc.createTextNode("mkyong"));
staff.appendChild(nickname);

//salary elements
Element salary = doc.createElement("salary");
salary.appendChild(doc.createTextNode("100000"));
staff.appendChild(salary);

//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("C:\\testing.xml"));
transformer.transform(source, result);

System.out.println("Done");

}catch(ParserConfigurationException pce){
pce.printStackTrace();
}catch(TransformerException tfe){
tfe.printStackTrace();
}

What is the best way to create XML files in Java?

If you just want to write an XML document having exact control over the creating of elements, attributes and other document components, you may use the XMLStreamWriter from the StAX API.

Java creating a new xml file and appending it

I simulated your code here and did realized the you are not creating a valid root element in XML file, that's why you getting the exception.

See my results that I am getting running the write method:

public static void main(String... x) {
Sentence s = new Sentence();
Main m = new Main();
List<Sentence> list = new ArrayList<Sentence>();
list.add(s);
m.write(list);
}

Sentence class:

public class Sentence {
public String[] getWordList() {
return new String[] { "w4", "w5", "w6" }; // previous: w1,w2,w3
}
}

file.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<text>
<sentence>
<word>w1</word>
<word>w2</word>
<word>w3</word>
</sentence>
<sentence>
<word>w4</word>
<word>w5</word>
<word>w6</word>
</sentence>
<sentence>
<word>w4</word>
<word>w5</word>
<word>w6</word>
</sentence>
</text>

Solution:
Just replace your code with the following:

// text element
Element rootElement = null;
if (!fileExist) {
rootElement = doc.createElement("text");
doc.appendChild(rootElement);
} else {
rootElement = doc.getDocumentElement(); // get the root [text] element
}

How to generate xml file with an existing dtd for sample of data using Java

A couple of observations/suggestions:

1) What do you need the XML output to look like?

Assume you have a Points class like this:

import java.util.Map;
import java.util.HashMap;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "root")
public class Points {

public Points() {};

public Points(Map<Position, Double> listOfPoints) {
this.listOfPoints = listOfPoints;
}

@XmlElement(name = "list_of_points")
private Map<Position, Double> listOfPoints;

public Map<Position, Double> getListOfPoints() {
if (listOfPoints == null) {
listOfPoints = new HashMap();
}
return this.listOfPoints;
}
}

and a Position class like this:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "position")
public class Position {

@XmlElement(required = true)
protected String x;
@XmlElement(required = true)
protected String y;

public String getX() {
return x;
}

public void setX(String value) {
this.x = value;
}

public String getY() {
return y;
}

public void setY(String value) {
this.y = value;
}

}

Without using a DTD, you can generate XML like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<listOfPoints>
<entry>
<key>
<x>pos1 x</x>
<y>pos1 y</y>
</key>
<value>123.456</value>
</entry>
<entry>
<key>
<x>pos2 x</x>
<y>pos2 y</y>
</key>
<value>456.789</value>
</entry>
</listOfPoints>
</root>

The code to do that is:

JAXBContext jc = JAXBContext.newInstance(Points.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
File xml = new File("/path/to/points.xml");
marshaller.marshal(points, xml);

Is that sufficient for your needs?

2) Using your DTD

I'm not sure how your DTD is going to help you, because it implies a set of unrelated and overlapping Java objects from which the final XML will be created.

To see what I mean, try it for yourself.

Using the xjc tool (see here), you can generate Java objects from your DTD:

/path/to/jdk/bin/xjc -d output -p org.ajames.jaxbdemo.points -dtd my_schema.dtd

Using these Java classes, you can populate your data structure (your listOfPoints). And then you can create the XML output from that (as shown above, using the JAXB marshaller).

But your DTD will create some not-very-useful objects...

So, that comes back to the initial question: What do you want your XML to look like?

3) Use an XSD?

If you manually create a sample of your required XML, you can then generate an XSD from it. There are various online tools to help with that. Then you can use the xjc command again (but this time for an XSD not a DTD). And then you can use the resulting Java objects to get the exact XML you need.

Create XML document using nodeList

You should do it like this:

  • you create a new org.w3c.dom.Document newXmlDoc where you store the nodes in your NodeList,
  • you create a new root element, and append it to newXmlDoc
  • then, for each node n in your NodeList, you import n in newXmlDoc, and then you append n as a child of root

Here is the code:

public static void main(String[] args) {
String exp = "/configs/markets/market";
String path = "src/a/testConfig.xml";
try {
Document xmlDocument = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(path);

XPath xPath = XPathFactory.newInstance().newXPath();
XPathExpression xPathExpression = xPath.compile(exp);
NodeList nodes = (NodeList) xPathExpression.
evaluate(xmlDocument, XPathConstants.NODESET);

Document newXmlDocument = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
Element root = newXmlDocument.createElement("root");
newXmlDocument.appendChild(root);
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
Node copyNode = newXmlDocument.importNode(node, true);
root.appendChild(copyNode);
}

printTree(newXmlDocument);
} catch (Exception ex) {
ex.printStackTrace();
}
}

public static void printXmlDocument(Document document) {
DOMImplementationLS domImplementationLS =
(DOMImplementationLS) document.getImplementation();
LSSerializer lsSerializer =
domImplementationLS.createLSSerializer();
String string = lsSerializer.writeToString(document);
System.out.println(string);
}

The output is:

<?xml version="1.0" encoding="UTF-16"?>
<root><market>
<name>Real</name>
</market><market>
<name>play</name>
</market></root>

Some notes:

  • I've changed exp to /configs/markets/market, because I suspect you want to copy the market elements, rather than the single markets element
  • for the printXmlDocument, I've used the interesting code in this answer

I hope this helps.


If you don't want to create a new root element, then you may use your original XPath expression, which returns a NodeList consisting of a single node (keep in mind that your XML must have a single root element) that you can directly add to your new XML document.

See following code, where I commented lines from the code above:

public static void main(String[] args) {
//String exp = "/configs/markets/market/";
String exp = "/configs/markets";
String path = "src/a/testConfig.xml";
try {
Document xmlDocument = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(path);

XPath xPath = XPathFactory.newInstance().newXPath();
XPathExpression xPathExpression = xPath.compile(exp);
NodeList nodes = (NodeList) xPathExpression.
evaluate(xmlDocument,XPathConstants.NODESET);

Document newXmlDocument = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
//Element root = newXmlDocument.createElement("root");
//newXmlDocument.appendChild(root);
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
Node copyNode = newXmlDocument.importNode(node, true);
newXmlDocument.appendChild(copyNode);
//root.appendChild(copyNode);
}

printXmlDocument(newXmlDocument);
} catch (Exception ex) {
ex.printStackTrace();
}
}

This will give you the following output:

<?xml version="1.0" encoding="UTF-16"?>
<markets>
<market>
<name>Real</name>
</market>
<market>
<name>play</name>
</market>
</markets>

Generating xml file with & using java

I need to write <name> Dolce & Gabanna </name> in an xml file using java.

No, you don't. Not unless you're trying to create an invalid file. Whatever code you're using is doing exactly the right thing - any XML parser reading the file will then unescape the & to & where appropriate.

From the XML 1.0 specification, section 2.4:

The ampersand character (&) and the left angle bracket (<) must not appear in their literal form, except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section. If they are needed elsewhere, they must be escaped using either numeric character references or the strings " & " and " < " respectively.

How to create XML file without external libraries in Java 9?

You can use these libraries in Java 9, but you need to require the module that contains them. Ensure that your module-info.java has a requirement for the java.xml module:

module myModule {
requires java.xml;
}

As you require more functionality from the JAXB modules, you will need to add more requires statements in your module-info.java file. For example, your module-info.java file may look more like the following when you are done:

module myModule {
java.xml
java.xml.bind
java.xml.ws
java.xml.ws.annotation
}

For more information, see How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException in Java 9.

How to read and write XML files?

Here is a quick DOM example that shows how to read and write a simple xml file with its dtd:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE roles SYSTEM "roles.dtd">
<roles>
<role1>User</role1>
<role2>Author</role2>
<role3>Admin</role3>
<role4/>
</roles>

and the dtd:

<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT roles (role1,role2,role3,role4)>
<!ELEMENT role1 (#PCDATA)>
<!ELEMENT role2 (#PCDATA)>
<!ELEMENT role3 (#PCDATA)>
<!ELEMENT role4 (#PCDATA)>

First import these:

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.xml.sax.*;
import org.w3c.dom.*;

Here are a few variables you will need:

private String role1 = null;
private String role2 = null;
private String role3 = null;
private String role4 = null;
private ArrayList<String> rolev;

Here is a reader (String xml is the name of your xml file):

public boolean readXML(String xml) {
rolev = new ArrayList<String>();
Document dom;
// Make an instance of the DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// use the factory to take an instance of the document builder
DocumentBuilder db = dbf.newDocumentBuilder();
// parse using the builder to get the DOM mapping of the
// XML file
dom = db.parse(xml);

Element doc = dom.getDocumentElement();

role1 = getTextValue(role1, doc, "role1");
if (role1 != null) {
if (!role1.isEmpty())
rolev.add(role1);
}
role2 = getTextValue(role2, doc, "role2");
if (role2 != null) {
if (!role2.isEmpty())
rolev.add(role2);
}
role3 = getTextValue(role3, doc, "role3");
if (role3 != null) {
if (!role3.isEmpty())
rolev.add(role3);
}
role4 = getTextValue(role4, doc, "role4");
if ( role4 != null) {
if (!role4.isEmpty())
rolev.add(role4);
}
return true;

} catch (ParserConfigurationException pce) {
System.out.println(pce.getMessage());
} catch (SAXException se) {
System.out.println(se.getMessage());
} catch (IOException ioe) {
System.err.println(ioe.getMessage());
}

return false;
}

And here a writer:

public void saveToXML(String xml) {
Document dom;
Element e = null;

// instance of a DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
// use factory to get an instance of document builder
DocumentBuilder db = dbf.newDocumentBuilder();
// create instance of DOM
dom = db.newDocument();

// create the root element
Element rootEle = dom.createElement("roles");

// create data elements and place them under root
e = dom.createElement("role1");
e.appendChild(dom.createTextNode(role1));
rootEle.appendChild(e);

e = dom.createElement("role2");
e.appendChild(dom.createTextNode(role2));
rootEle.appendChild(e);

e = dom.createElement("role3");
e.appendChild(dom.createTextNode(role3));
rootEle.appendChild(e);

e = dom.createElement("role4");
e.appendChild(dom.createTextNode(role4));
rootEle.appendChild(e);

dom.appendChild(rootEle);

try {
Transformer tr = TransformerFactory.newInstance().newTransformer();
tr.setOutputProperty(OutputKeys.INDENT, "yes");
tr.setOutputProperty(OutputKeys.METHOD, "xml");
tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tr.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "roles.dtd");
tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

// send DOM to file
tr.transform(new DOMSource(dom),
new StreamResult(new FileOutputStream(xml)));

} catch (TransformerException te) {
System.out.println(te.getMessage());
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
} catch (ParserConfigurationException pce) {
System.out.println("UsersXML: Error trying to instantiate DocumentBuilder " + pce);
}
}

getTextValue is here:

private String getTextValue(String def, Element doc, String tag) {
String value = def;
NodeList nl;
nl = doc.getElementsByTagName(tag);
if (nl.getLength() > 0 && nl.item(0).hasChildNodes()) {
value = nl.item(0).getFirstChild().getNodeValue();
}
return value;
}

Add a few accessors and mutators and you are done!



Related Topics



Leave a reply



Submit