I would like to rename my root node of an XML in Java.
I tried various solutions but none did work.
My code:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
File xmlFile = new File("C:/test.xml");
Document doc = builder.parse(new FileInputStream(xmlFile));
File xmiFile = new File("C:/test.xmi");
FileMover.copyFile(xmlFile, xmiFile);
Document doc2 = builder.parse(new FileInputStream(xmiFile));
doc2.importNode(doc.getDocumentElement(), true);
doc2.getElementsByTagName("report");
Node reportNode = doc2.getDocumentElement();
Element reportElement = (Element) reportNode;
doc2.renameNode(reportElement, "reports.dtd", "report:ReportType");
Transformer transformer = TransformerFactory.newInstance().newTransformer();
Source source2 = new DOMSource(doc2.getDocumentElement());
StringWriter out = new StringWriter();
Result result2 = new StreamResult(out);
transformer.transform(source2, result2);
Running the code, I get this exception:
Exception in thread "Main Thread" org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.insertBefore(CoreDocumentImpl.java:392)
at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.renameNode(CoreDocumentImpl.java:1047)
at XMIConverter.main(XMIConverter.java:57)
Related
I am trying to parse a large xml file using DOM Parser and Xpath, but it seems like my code breaks as it's a large xml file (60000 lines). When I try and print the xml, it starts printing from the middle of the xml. Any ideas how I can avoid this?
Regards
FileInputStream file = new FileInputStream(new File(filePath));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
disclaimer = xPath.compile(disclaimerPath + File.separator + "title").evaluate(xmlDocument);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(xmlDocument), new StreamResult(writer));
System.out.println(writer.getBuffer().toString().replaceAll("\n|\r", ""));
Hello Im new in useing xml and now trying to append new nodes for existing xml file.
This is my code to write a xml
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBulder = docFactory.newDocumentBuilder();
//root mainElement
Document doc = docBulder.newDocument();
Element rootElement = doc.createElement("Books");
doc.appendChild(rootElement);
//root Book
Element Book = doc.createElement("Book");
rootElement.appendChild(Book);
//setting ganre for a book
Attr att = doc.createAttribute("ganre");
att.setValue(ganre);
Book.setAttributeNode(att);
//book id
Element bookId = doc.createElement("bookId");
bookId.appendChild(doc.createTextNode(randomString(4)));
Book.appendChild(bookId);
//bookname element
Element bookname = doc.createElement("bookName");
bookname.appendChild(doc.createTextNode(name));
Book.appendChild(bookname);
//book author
Element bookAuthor = doc.createElement("bookAuthor");
bookAuthor.appendChild(doc.createTextNode(author));
Book.appendChild(bookAuthor);
//book year
Element bookYear = doc.createElement("bookYear");
bookYear.appendChild(doc.createTextNode(String.valueOf(year)));
Book.appendChild(bookYear);
//book available
Element bookAvail = doc.createElement("bookAvailable");
bookAvail.appendChild(doc.createTextNode(String.valueOf(free)));
Book.appendChild(bookAvail);
//write in a XMLFile
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("Test/Books.xml"));
transformer.transform(source, result);
System.out.println("File saved!");
this is how I trying to append new nodes
File fXmlFile = new File("Test/Books.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
Node books = doc.getFirstChild();
Element newBook = doc.createElement("Book");
[here the troubles comes]
what i want to do is rewrite file like this:
<Books>
<Book ganre="fantasy">
<bookId>7111</bookId>
<bookName>Tron</bookName>
<bookAuthor>Brawm</bookAuthor>
<bookYear>15</bookYear>
<bookAvailable>true</bookAvailable>
</Book>
<Book ganre="action">
<bookId>312</bookId>
<bookName>Corn</bookName>
<bookAuthor>Down</bookAuthor>
<bookYear>23</bookYear>
<bookAvailable>false</bookAvailable>
</Book>
</Books>
but every time Im can only rewrite or damage the xml file.
ps Im getting all my bookName's and so on from the input
I can just suggest to use the JDom library. Its very easy to use and implement, always worked for me.
JDOM is, quite simply, a Java representation of an XML document. JDOM provides a way to represent that document for easy and efficient reading, manipulation, and writing. It has a straightforward API, is a lightweight and fast, and is optimized for the Java programmer. It’s an alternative to DOM and SAX, although it integrates well with both DOM and SAX.
There are some good tutorials at mykong.com explaining how to read, modify and create xml-files :
http://www.mkyong.com/java/how-to-modify-xml-file-in-java-jdom/
problem was solved. My solution is:
File fXmlFile = new File("Test/Books.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
// doc.getDocumentElement().normalize();
Element nList = doc.getDocumentElement();
System.out.println("-----------------------");
//root a new book
Element newBook = doc.createElement("Book");
//setting ganre for a book
Attr att = doc.createAttribute("ganre");
att.setValue(ganre);
newBook.setAttributeNode(att);
//book id
Element bookId = doc.createElement("bookId");
bookId.appendChild(doc.createTextNode(randomString(4)));
newBook.appendChild(bookId);
//bookname element
Element bookname = doc.createElement("bookName");
bookname.appendChild(doc.createTextNode(name));
newBook.appendChild(bookname);
//book author
Element bookAuthor = doc.createElement("bookAuthor");
bookAuthor.appendChild(doc.createTextNode(author));
newBook.appendChild(bookAuthor);
//book year
Element bookYear = doc.createElement("bookYear");
bookYear.appendChild(doc.createTextNode(String.valueOf(year)));
newBook.appendChild(bookYear);
//book available
Element bookAvail = doc.createElement("bookAvailable");
bookAvail.appendChild(doc.createTextNode(String.valueOf(free)));
newBook.appendChild(bookAvail);
nList.appendChild(newBook);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//initialize StreamResult with File object to save to file
StreamResult result = new StreamResult(new File("Test/Books.xml"));
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
System.out.println("DONE");
I have an XML document which has null values in its Value tag (something similar to below)
<ns2:Attribute Name="Store" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<ns2:AttributeValue/>
</ns2:Attribute>
Now, I have to write Java code to modify the values as below.
<ns2:Attribute Name="Store" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<ns2:AttributeValue>ABCDEF</ns2:AttributeValue>
</ns2:Attribute>
I am using DOM parser to parse the XML. I am able to delete the null tag for " but not able to add new values. I am not even sure if we have a direct way to replace or add the values.
Below is the code I am using to remove the child("")
Node aNode = nodeList.item(i);
eElement = (Element) aNode;
eElement.removeChild(eElement.getFirstChild().getNextSibling());
Thanks in advance
Just add data through setTextContent to the element. Sample code is as below:
public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException, TransformerException {
String xml = "<ns2:Attribute Name=\"Store\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\"><ns2:AttributeValue/></ns2:Attribute>";
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("ns2:AttributeValue");
for (int i=0;i<nList.getLength();i++) {
Element elem = (Element)nList.item(i);
elem.setTextContent("Content"+i);
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
System.out.println(nList.getLength());
}
I have read XML file in Java with such code:
File file = new File("file.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
NodeList nodeLst = doc.getElementsByTagName("record");
for (int i = 0; i < nodeLst.getLength(); i++) {
Node node = nodeLst.item(i);
...
}
So, how I can get full xml content from node instance? (including all tags, attributes etc.)
Thanks.
Check out this other answer from stackoverflow.
You would use a DOMSource (instead of the StreamSource), and pass your node in the constructor.
Then you can transform the node into a String.
Quick sample:
public class NodeToString {
public static void main(String[] args) throws TransformerException, ParserConfigurationException, SAXException, IOException {
// just to get access to a Node
String fakeXml = "<!-- Document comment -->\n <aaa>\n\n<bbb/> \n<ccc/></aaa>";
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = docBuilder.parse(new InputSource(new StringReader(fakeXml)));
Node node = doc.getDocumentElement();
// test the method
System.out.println(node2String(node));
}
static String node2String(Node node) throws TransformerFactoryConfigurationError, TransformerException {
// you may prefer to use single instances of Transformer, and
// StringWriter rather than create each time. That would be up to your
// judgement and whether your app is single threaded etc
StreamResult xmlOutput = new StreamResult(new StringWriter());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new DOMSource(node), xmlOutput);
return xmlOutput.getWriter().toString();
}
}
Has anybody seen anything like this before? I will post the xsl and xml if I have to but I would have to take sensitive data out of it.
The code used to handle the XSL transformation:
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new DOMSource( xslDoc));
DOMResult domresult = new DOMResult();
transformer.transform(new DOMSource(xmlDoc), domresult);
Node node = domresult.getNode();
resultDoc = (Document) node;
Never seen it going blank. For JAVA6 (also compatible with 1.5), I have the following code that is working, the difference seems to on TransformerFactory used.
private DocumentBuilderFactory factory;
private DocumentBuilder builder;
private Transformer xformer;
//presetup - needs to be done just once
factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
builder = factory.newDocumentBuilder();
xformer = TransformerFactory.newInstance().newTransformer();
//Transform the file
Source source = new DOMSource(doc);
String oFileName = "output.xml";
File oFile = new File(outputDirectory + "/" + oFileName);
Result result = new StreamResult(oFile);
xformer.transform(source, result);
Does this correct your issue?