13

I have a xml file as object in Java as org.w3c.dom.Document doc and I want to convert this into File file. How can I convert the type Document to File? thanks

I want to add metadata elements in an existing xml file (standard dita) with type File. I know a way to add elements to the file, but then I have to convert the file to a org.w3c.dom.Document. I did that with the method loadXML:

private Document loadXML(File f) throws Exception{ 
DocumentBuilder b = DocumentBuilderFactory.newInstance().newDocumentBuilder();
return builder.parse(f);

After that I change the org.w3c.dom.Document, then I want to continue with the flow of the program and I have to convert the Document doc back to a File file.

What is a efficient way to do that? Or what is a better solution to get some elements in a xml File without converting it?

lfurini
  • 3,729
  • 4
  • 30
  • 48
jer08
  • 143
  • 1
  • 1
  • 6

2 Answers2

18

You can use a Transformer class to output the entire XML content to a File, as showed below:

Document doc =...

// write the content into xml file
    DOMSource source = new DOMSource(doc);
    FileWriter writer = new FileWriter(new File("/tmp/output.xml"));
    StreamResult result = new StreamResult(writer);

    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    transformer.transform(source, result);
lfurini
  • 3,729
  • 4
  • 30
  • 48
Mario Cairone
  • 1,071
  • 7
  • 11
1

With JDK 1.8.0 a short way is to use the built-in XMLSerializer (which was introduced with JDK 1.4 as a fork of Apache Xerces)

import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

Document doc = //use your method loadXML(File f)

//change Document

java.io.Writer writer = new java.io.FileWriter("MyOutput.xml");
XMLSerializer xml = new XMLSerializer(writer, null);
xml.serialize(doc);

Use an object of type OutputFormat to configure output, for example like this:

OutputFormat format = new OutputFormat(Method.XML, StandardCharsets.UTF_8.toString(), true);
format.setIndent(4);
format.setLineWidth(80);
format.setPreserveEmptyAttributes(true);
format.setPreserveSpace(true);
XMLSerializer xml = new XMLSerializer(writer, format);

Note that the classes are from com.sun.* package which is not documented and therefore generally is not seen as the preferred way of doing things. However, with javax.xml.transform.OutputKeys you cannot specify the amount of indentation or line width for example. So, if this is important then this solution should help.

Würgspaß
  • 4,660
  • 2
  • 25
  • 41
  • 1
    This is a shorter than using the transformer in the accepted answer, but shouldn't we stay away from `com.sun` classes? – Paul Samsotha Aug 10 '18 at 18:50
  • Depends on your needs or policies. Please note that `com.sun.*` is not `sun.*` This code has proved to be stable for more than a year now and other well-known frameworks use `com.sun.*` as well. But, yes, in the unlikely event of an incompatible change, you have to be prepared to change your code. Which should not be a big deal, if your company policy contains some words like `agile` or `continuous refactoring`. For further details: https://stackoverflow.com/questions/8565708/what-is-inside-com-sun-package – Würgspaß Aug 14 '18 at 08:56