Sorry, got it right now using a XMLSerializer instead of the Transformer...
Up vote 0 down vote favorite 1 share g+ share fb share tw.
I am working on a system that should be able to read any (or at least, any well-formed) XML file, manipulate a few nodes and write them back into that same file. I want my code to be as generic as possible and I don't want hardcoded references to Schema/Doctype information anywhere in my code. The doctype information is in the source document, I want to keep exactly that doctype information and not provide it again from within my code.
If a document has no DocType, I won't add one. I do not care about the form or content of these files at all, except for my few nodes. Custom EntityResolvers or StreamFilters to omit or otherwise manipulate the source information (It is already a pity that namespace information seems somehow inaccessible from the document file where it is declared, but I can manage by using uglier XPaths) DTD validation.
I don't have the referenced DTDs, I don't want to include them and Node manipulation is perfectly possible without knowing about them. The aim is to have the source file entirely unchanged except for the changed Nodes, which are retrieved via XPath. I would like to get away with the standard javax.
Xml stuff. My progress so far: DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory. SetAttribute("http://xml.org/sax/features/namespaces", true); factory.
SetAttribute("http://xml.org/sax/features/validation", false); factory. SetAttribute("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); factory. SetAttribute("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); factory.
SetNamespaceAware(true); factory. SetIgnoringElementContentWhitespace(false); factory. SetIgnoringComments(false); factory.
SetValidating(false); DocumentBuilder builder = factory. NewDocumentBuilder(); Document document = builder. Parse(new InputSource(inStream)); This loads the XML source into a org.
W3c.dom. Document successfully, ignoring DTD validation. I can do my replacements and then I use Source source = new DOMSource(document); Result result = new StreamResult(getOutputStream(getPath())); // Write the DOM document to the file Transformer xformer = TransformerFactory.newInstance().newTransformer(); xformer.
Transform(source, result); to write it back. Which is nearly perfect. But the Doctype tag is gone, no matter what I do.
While debugging, I saw that there is a DeferredDoctypeImpl log4j:configuration: null object in the Document object after parsing, but it is somehow wrong, empty or ignored. The file I tested on starts like this (but it is the same for other file types): ... I think there are a lot of (easy? ) ways involving hacks or pulling additional JARs into the project.
But I would rather like to have it with the tools I already use. Java xml dtd doctype link|improve this question asked Feb 24 '09 at 16:04Stephan.
Here's how you could do it using the LSSerializer found in JDK: private void writeDocument(Document doc, String filename) throws IOException { Writer writer = null; try { /* * Could extract "ls" to an instance attribute, so it can be reused. */ DOMImplementationLS ls = (DOMImplementationLS) DOMImplementationRegistry.newInstance(). GetDOMImplementation("LS"); writer = new OutputStreamWriter(new FileOutputStream(filename)); LSOutput lsout = ls.createLSOutput(); lsout.
SetCharacterStream(writer); /* * If "doc" has been constructed by parsing an XML document, we * should keep its encoding when serializing it; if it has been * constructed in memory, its encoding has to be decided by the * client code. */ lsout. SetEncoding(doc.getXmlEncoding()); LSSerializer serializer = ls.
CreateLSSerializer(); serializer. Write(doc, lsout); } catch (Exception e) { throw new IOException(e); } finally { if (writer! = null) writer.close(); } } Needed imports: import java.io.
FileOutputStream; import java.io. IOException; import java.io. OutputStreamWriter; import java.io.
Writer; import org. W3c.dom. Document; import org.
W3c.dom.bootstrap. DOMImplementationRegistry; import org. W3c.dom.ls.
DOMImplementationLS; import org. W3c.dom.ls. LSOutput; import org.
W3c.dom.ls. LSSerializer; I know this is an old question which has already been answered, but I think the technical details might help someone.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.