So I have this wich should put into an xml file a movie.
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse("D:\\College\\Java Eclipse\\tema5\\Movies\\Movies.xml");
try {
Element rootElement = doc.createElement("Movie");
doc.appendChild(rootElement);
// firstname elements
Element id = doc.createElement("Id");
id.appendChild(doc.createTextNode("3"));
rootElement.appendChild(id);
// lastname elements
Element name = doc.createElement("Name");
name.appendChild(doc.createTextNode("Movie 3"));
rootElement.appendChild(name);
// nickname elements
Element category = doc.createElement("Category");
category.appendChild(doc.createTextNode("Animation"));
rootElement.appendChild(category);
// salary elements
Element releasedate = doc.createElement("ReleaseDate");
releasedate.appendChild(doc.createTextNode("10-Jun-2012"));
rootElement.appendChild(releasedate);
Element rating = doc.createElement("Rating");
rating.appendChild(doc.createTextNode("10"));
rootElement.appendChild(rating);
// 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("D:\\College\\Java Eclipse\\tema5\\Movies\\Movies.xml"));
// Output to console for testing
// StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
The problem is that in my xml file I already have two movies, when it tries to put the third one it succeeds but at the forth one it dies. I think it's because of the nodes and I want to know how to reposition the last to the end of the file so I can place more movies. This is the xml doc after the first insertion.
<?xml version="1.0" encoding="UTF-8" standalone="no"?><Movie>
<Movie>
<Id>1</Id>
<Name>Movie 1</Name>
<Category>Action</Category>
<ReleaseDate>22-JUN-2010</ReleaseDate>
<Rating>9</Rating>
</Movie>
<Movie>
<Id>2</Id>
<Name>Movie 2</Name>
<Category>Comedy</Category>
<ReleaseDate>2-JUN-2011</ReleaseDate>
<Rating>8</Rating>
</Movie>
</Movie>
<Movie>
<Id>3</Id>
<Name>Movie 3</Name>
<Category>Animation</Category>
<ReleaseDate>10-Jun-2012</ReleaseDate>
<Rating>10</Rating>
</Movie>
Element docRoot = doc.getDocumentElement();
Element rootElement = doc.createElement("Movie");
docRoot.appendChild(rootElement);
I would suggest renaming your rootElement variable to newMovie as it is missleading. You can only have one root element in xml, and you get it by doc.getDocumentElement()
Related
I want to create a xml file and I've seen this example (https://www.mkyong.com/java/how-to-create-xml-file-in-java-dom/) however, I want to generate it inside a loop method.
<company>
<staff id="1">
<firstname>yong</firstname>
<lastname>mook kim</lastname>
<nickname>mkyong</nickname>
<salary>100000</salary>
</staff>
<staff id="2">
<firstname>hif</firstname>
<lastname>kiuk kim</lastname>
<nickname>gonuy</nickname>
<salary>50000</salary>
</staff>
</company>
But, using the code:
public void printXml(String firstName, String lastName, String nickname, String salary) {
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 firstnameElement = doc.createElement("firstname");
firstnameElement.appendChild(doc.createTextNode(firstName));
staff.appendChild(firstnameElement);
// lastname elements
Element lastnameElement = doc.createElement("lastname");
lastnameElement.appendChild(doc.createTextNode(lastName));
staff.appendChild(lastnameElement);
// nickname elements
Element nicknameElement = doc.createElement("nickname");
nicknameElement.appendChild(doc.createTextNode(nickname));
staff.appendChild(nicknameElement);
// salary elements
Element salaryElement = doc.createElement("salary");
salaryElement.appendChild(doc.createTextNode(salary));
staff.appendChild(salaryElement);
// 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:\\file.xml"));
// Output to console for testing
// StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
System.out.println("File saved!");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
}
the information on the loop about the company staff is always being replaced and it save only the last info:
for (Staff staff: staffList){
String firstName = staff.getFirstName();
String lastName = staff.getLastName();
String nickname = staff.getNickname ();
double salary = staff.getSalary();
printXml(firstName, lastName, nickname, salary);
<company>
<staff id="2">
<firstname>hif</firstname>
<lastname>kiuk kim</lastname>
<nickname>gonuy</nickname>
<salary>50000</salary>
</staff>
</company>
How can I save all info that I get during the loop? Thank you.
Your'e overwriting the file instead of appending to it.
You should initialize StreamResult with a stream that can write to a file as well as append to it.
For example, you can use FileOutputStream, and pass true for its constructor for appending.
However, you need to close the stream, so one option would be changing your code so that printXml would become getXml, and your code would then look as follows:
FileOutputStream stream = new FileOutputStream("C:\\file.xml", true);
StreamResult result = new StreamResult(stream);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
for (Staff staff: staffList){
DOMSource source = getXml(staff); // call staff's getters inside getXml
transformer.transform(source, result);
}
stream.close();
(You should also move lines 3-4 above to a method named getTransformer).
I searched in SO but I did not found nothing that solves my problem. I hope some one can help me.
I am building a XML file and I need to remove the Namespace xmlns.
That is my code
Document xmlDocument = new Document();
Namespace ns1 = Namespace.getNamespace("urn:iso:std:iso:20022:tech:xsd:pain.001.001.03");
Namespace ns2 = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Element root = new Element("Document", ns1);
root.addNamespaceDeclaration(ns2);
xmlDocument.setRootElement(root);
Element CstmrCdtTrfInitn = new Element("CstmrCdtTrfInitn");
root.addContent(CstmrCdtTrfInitn);
PrintDocumentHandler pdh = new PrintDocumentHandler();
pdh.setXmlDocument(xmlDocument);
request.getSession(false).setAttribute("pdh", pdh);
ByteArrayOutputStream sos = new ByteArrayOutputStream();
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
Format format = outputter.getFormat();
format.setEncoding(SOPConstants.ENCODING_SCHEMA);
outputter.setFormat(format);
outputter.output(root, sos);
sos.flush();
return sos;
And this is the created XML-File
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">
<CstmrCdtTrfInitn xmlns=""/>
</Document>
I have to remove the namespace xmlns from the tag CstmrCdtTrfInitn.
Many thanks in advance.
Namespace declaration without prefix (xmlns="...") is known as default namespace. Notice that, unlike prefixed namespace, descendant elements without prefix inherit ancestor's default namespace implicitly. So in the XML below, <CstmrCdtTrfInitn> is considered in the namespace urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 :
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">
<CstmrCdtTrfInitn/>
</Document>
If this is the wanted result, instead of trying to remove xmlns="" later, you should try to create CstmrCdtTrfInitn using the same namespace as Document in the first place :
Element CstmrCdtTrfInitn = new Element("CstmrCdtTrfInitn", ns1);
I did some code for you, I dont know what package You are using... If You only want to remove the xmlns attribute from the CstmrCdtTrfInitn tag try with this code as other method to generate XML (I just modified this):
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("Document");
rootElement.setAttribute("xmlns", "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03");
rootElement.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
doc.appendChild(rootElement);
// staff elements
Element CstmrCdtTrfInitn = doc.createElement("CstmrCdtTrfInitn");
rootElement.appendChild(CstmrCdtTrfInitn);
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
// Output to console for testing
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
I need to set prefix of the element in my xml. I need to print the xml in the format below:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<cars xmlns:dcterms="http://purl.org/dc/terms/" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<supercars company="Ferrari">
<dcterms:carname type="formula one">Ferrari 101</dcterms:carname>
<msxsl:carname type="sports">Ferrari 202</msxsl:carname>
</supercars>
</cars>
However, I am not able to add the prefix in my XML. What I am getting is this.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<cars xmlns:dcterms="http://purl.org/dc/terms/" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<supercars company="Ferrari">
<carname type="formula one">Ferrari 101</carname>
<carname type="sports">Ferrari 202</carname>
</supercars>
</cars>
Following is my Java Code:
public static void main(String args[]) {
try {
DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder =
dbFactory.newDocumentBuilder();
Document doc = dBuilder.newDocument();
// root element
Element rootElement = doc.createElement("cars");
rootElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:dcterms", "http://purl.org/dc/terms/");
rootElement.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:msxsl", "urn:schemas-microsoft-com:xslt");
doc.appendChild(rootElement);
// supercars element
Element supercar = doc.createElement("supercars");
rootElement.appendChild(supercar);
// setting attribute to element
Attr attr = doc.createAttribute("company");
attr.setValue("Ferrari");
// supercar.setAttributeNodeNS(attr);
supercar.setAttributeNode(attr);
// carname element
Element carname = doc.createElement("carname");
Attr attrType = doc.createAttribute("type");
attrType.setValue("formula one");
carname.setAttributeNode(attrType);
carname.appendChild(
doc.createTextNode("Ferrari 101"));
supercar.appendChild(carname);
Element carname1 = doc.createElement("carname");
Attr attrType1 = doc.createAttribute("type");
attrType1.setValue("sports");
carname1.setAttributeNode(attrType1);
carname1.appendChild(
doc.createTextNode("Ferrari 202"));
supercar.appendChild(carname1);
// write the content into xml file
TransformerFactory transformerFactory =
TransformerFactory.newInstance();
Transformer transformer =
transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(doc);
StreamResult result =
new StreamResult(new File("cars.xml"));
transformer.transform(source, result);
// Output to console for testing
StreamResult consoleResult =
new StreamResult(System.out);
transformer.transform(source, consoleResult);
} catch (Exception e) {
e.printStackTrace();
}
}
}
And I checked this link Adding namespace prefix XML String using XML DOM. However, this only talks about the SAX way of doing thing. I need to do this in DOM.
I tried setPrefix method and it is throwing me NAMESPACE_ERR
First of all, make sure you set dbFactory.setNamespaceAware(true);, if you want to work with a DOM supporting namespaces.
Then use createElementNS, e.g. Element carname = doc.createElementNS("http://purl.org/dc/terms/", "dcterms:carname");, to create elements in a namespace. Use the same approach for the element in the other namespace.
I have the following XML, I would like to add another "product" to the xml.
<?xml version="1.0" encoding="ISO-8859-1"?>
<products>
<product>
<name>Computer</name>
<code>PC1003</code>
<description>Basic Computer</description>
<price>399.99</price>
</product>
<product>
<name>Monitor</name>
<code>MN1003</code>
<description>LCD Monitor</description>
<price>99.99</price>
</product>
<product>
<name>Printer</name>
<code>PR1003x</code>
<description>Inkjet Printer</description>
<price>54.23</price>
</product>
</products>
This is the code I have so far:
// Variables
File file = new File("db_products.xml"); // set xml to parse
// Create builders
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(file); // load xml file
doc.getDocumentElement().normalize();
doc.createElement("product");
I don't really care where the new "product" section is added. I just can't seem to grasp what is the difference between a node and an element. I'm assuming the correct way to add a new "product" section would be to add a child to "products" and then add children (name,code,etc.) to "product".
Any help on how to easily do this, or a link to a simple tutorial would be appreciated.
What you need to do is retrieve the products element first and then call the appendChild on that element. Something like this:
Element productElement = doc.createElement("product");
productElement.setAttribute("name", "value");
//Other name value pairs...
//Append the products element to the right spot.
Element productsElement = (Element) doc.getElementByTagName("products").item(0);
productsElement.appendChild(productElement);
//Convert doc to xml string
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
String xmlAsString = writer.toString();
I have a XML document, i want to insert more number of tag. example
<data>
<tag1>1St tag</tag1>
<tag2>2nd tag</tag2>
<tag3>NewTag</tag3>
<tag4>4th tag</tag4>
</data>
I have tried to insert the data, but whenever i insert the data the inserting element occurred at once
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setIgnoringComments(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new File("File.xml"));
NodeList nodes = doc.getElementsByTagName("tag4");
Text a = doc.createTextNode("value");
Element p = doc.createElement("tag3");
p.appendChild(a);
for (int i = 0; i < nodes.getLength(); i++) {
nodes.item(i).getParentNode().insertBefore(p, nodes.item(i));
}
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);
String xmlOutput = result.getWriter().toString();
System.out.println(xmlOutput);
System.out.println("Done");
This code is adding new element but whenever i insert new tag it rewrite the new tag name into existing tag. How to rectify the issue. To be simple i want to insert more tag in XML file.
// Add a text node to the element
element.appendChild(doc.createTextNode("D"));
// Add a text node to the beginning of the element
element.insertBefore(doc.createTextNode("A"), element.getFirstChild());
// Add a text node before the last child of the element
element.insertBefore(doc.createTextNode("C"), element.getLastChild());
// Add another element after the first child of the root element
Element element2 = doc.createElement("item");
element.insertBefore(element2, element.getFirstChild().getNextSibling());
// Add a text node in front of the new item element
element2.getParentNode().insertBefore(doc.createTextNode("B"), element2);
Sample piece of code which will be helpful for you to add