org.w3c.dom.Document to String without javax.xml.transform - java

I've spent a while looking around on Google for a way to convert a org.w3c.dom.Document to a string representation of the whole DOM tree, so I can save the object to file system.
However all the solutions I've found use javax.xml.transform.Transformer which isn't supported as part of the Android 2.1 API. How can I do this without using this class/containing package?

Please try this code:
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse("/path/to/file.xml");
DOMImplementation domImpl = ownerDocument.getImplementation();
DOMImplementationLS domImplLS = (DOMImplementationLS)domImpl.getFeature("LS", "3.0");
LSSerializer serializer = domImplLS.createLSSerializer();
serializer.getDomConfig().setParameter("xml-declaration", Boolean.valueOf(false));
LSOutput lsOutput = domImplLS.createLSOutput();
lsOutput.setCharacterStream(output);
serializer.write(doc, lsOutput);

To avoid using Transformer you should manually iterate over your xml tree, otherwise you can rely on some external libraries. You should take a look here.

Related

Evaluation of XPath changes with different environments

I have a standalone java project in which i am evaluation XPath from my xml file and it giving the right result.
When i integrated my source code into an application deployed on websphere 7, the result is not ok anymore.
After verification, i found that in the first case (standalone project) the Document is well-built (all the nodes from the root are recognized) and in the second case (source code added in the deployed app on WS 7) the root node is missing in the Document.
I worked with the same implementation of "DocumentBuilderFactory" in both cases and the problem persists.
This is the code i used :
domFactory = DocumentBuilderFactory.newInstance();
xmlContent = new byte[inputStream.available()];
inputStream.read(xmlContent);
ByteArrayInputStream bais = new ByteArrayInputStream(xmlContent);
DocumentBuilder documentBuilder = domFactory.newDocumentBuilder();
document = documentBuilder .parse(bais);
xPATH = XPathFactory.newInstance().newXPath();
transformerFactory = TransformerFactory.newInstance();
transformer = transformerFactory.newTransformer();
The implementation of DomFactory is : "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl" from the jar xerces-impl.1.5
Any ideas would be helpfull.
The InputStream.read(byte[]) method might or might not fill the array passed to it. At first, you were lucky; just because the code worked once doesn't mean it was guaranteed to work every time or on every platform.
The other problem is that the contract of the InputStream.available() method specifically states:
Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.
In your case, there is a pretty simple solution. You already have an InputStream. Do not read it into a byte array; delete all uses of xmlContent, bais, and available(). Parse the original InputStream instead:
DocumentBuilder documentBuilder = domFactory.newDocumentBuilder();
document = documentBuilder.parse(inputStream);
xPATH = XPathFactory.newInstance().newXPath();
transformerFactory = TransformerFactory.newInstance();
transformer = transformerFactory.newTransformer();

Convert org.w3c.dom.Node into Document

I have a Node from one Document. I want to take that Node and turn it into the root node of a new Document.
Only way I can think of is the following:
Node node = someChildNodeFromDifferentDocument;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document newDocument = builder.newDocument();
newDocument.importNode(node);
newDocument.appendChild(node);
This works, but I feel it is rather annoyingly verbose. Is there a less verbose/more direct way I'm not seeing, or do I just have to do it this way?
The code did not work for me - but with some changes from this related question I could get it to work as follows:
Node node = someChildNodeFromDifferentDocument;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document newDocument = builder.newDocument();
Node importedNode = newDocument.importNode(node, true);
newDocument.appendChild(importedNode);
That looks about right to me. While it does look generally verbose, it certainly doesn't look significantly more verbose than other code using the DOM API. It's just an annoying API, unfortunately.
Of course, it's simpler if you've already got a DocumentBuilder from elsewhere - that would get rid of quite a lot of your code.
document from Node
Document document = node.getOwnerDocument();
Maybe you can use this code:
String xmlResult = XMLHelper.nodeToXMLString(node);
Document docDataItem = DOMHelper.stringToDOM(xmlResult);
You can simply clone the old document using cloneNode and then typecast it to Document like below:
Document newDocument = (Document) node.cloneNode(true);

create simple xml in Java

I am trying to build server that sends a xml file to client. I am getting info from db and wants to build from that xml file.
But I have a problem with:
DocumentBuilder documentBuilder = null;
Document doc =documentBuilder.newDocument();
I am getting NullPointerException. Here is me full code:
public void createXmlTree() throws Exception {
//This method creates an element node
DocumentBuilder documentBuilder = null;
Document doc =documentBuilder.newDocument();
Element root = doc.createElement("items");
//adding a node after the last child node of the specified node.
doc.appendChild(root);
for(int i=0;i<db.stories.size();i++){
Element child = doc.createElement("item");
root.appendChild(child);
Element child1 = doc.createElement("title");
child.appendChild(child1);
Text text = doc.createTextNode(db.stories.get(i).title);
child1.appendChild(text);
//Comment comment = doc.createComment("Employee in roseindia");
//child.appendChild(comment);
Element child2 = doc.createElement("date");
child.appendChild(child2);
Text text2 = doc.createTextNode(db.stories.get(i).date);
child2.appendChild(text2);
Element child3 = doc.createElement("text");
child.appendChild(child3);
Text text3 = doc.createTextNode(db.stories.get(i).text);
child3.appendChild(text3);
root.appendChild(child3);
Well yes, you would get a NullPointerException. You're calling a method on a null reference - very clearly, given that you've assigned the documentBuilder a null value on the line before. You need to get an instance of DocumentBuilder to start with. For example:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
of course you are getting a NullPointerException, your DocumentBuilder is null.
Try instantiating it first.
// Step 1: create a DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// Step 2: create a DocumentBuilder
DocumentBuilder db = dbf.newDocumentBuilder();
Guys are right about DocumentBuilder. But may I offer you other solution? Your servlet mostly deals with generating of XML itself, i.e. produces kind of markup. This is the purpose of JSP. You can implement simple JSP page that will actually contain template of your XML and some code that inserts dynamic data. This is much simpler and easier to maintain.
Yes, JSP typically generate HTML but no-one said that they cannot generate XML or any other text format. Just do not forget to set content type to text/xml.
Do you really need to write you XML manually?
Do you have the XSD of the XML you want to write?
Because, it would be easier to generate some classes using XJC/JAXB and use the marshaller to write your XML file.

Parse a single Line of XML into a HashMap

I'm building an android app that communicates to a web server and am struggling with the following scenario:
Given ONE line of XML in a String eg:
"<test one="1" two="2" />"
I would like to extract the values into a HashMap so that:
map.get("one") = "1"
map.get("two") = "2"
I already can do this with a full XML document using the SAX Parser, this complains when i try to just give it the above string with a MalformedUrlException: Protocol not found
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
Document doc = null;
builder = factory.newDocumentBuilder();
doc = builder.parse("<test one="1" two="2" />"); //here
I realize some regex could do this but Id really rather do it properly.
The same behaviour can be found at http://metacpan.org/pod/XML::Simple#XMLin which is what the web server uses.
Can anyone help? Thanks :D
DocumentBuilder.parse(String) treats the string as a URL. Try this instead:
Document doc = builder.parse(new InputSource(new StringReader(text)));
(where text contains the XML, of course).

Parsing xml response

I have a JAVA application where I am sending some xml requests and receiving xml responses. I first receive response in string and then write a file and storing this file into file system. Then while parsing the xml response file I am accessing this from file system and use some of the data for further business logic.
File file = new File("log\\XMLMessage\\LastXMLResponse.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
Now I am thinking to distribute this JAVA application via Java Web Start (JWS) application and as I know I cannot keep this file into jar file since there will be modification in this file on regular basis.
What do you suggest me to do? Can I parse the String directly (no need to store the response into file)?
Document doc = db.parse(xmlMessage);
or where can I keep this file? I don't want to show this file to the user of my application.
Take the String, make a StringReader from String, make a InputSource from StringReader, then call parse on your DocumentBuilder.
Yes, you can parse the string directly,no need to store it in a file.
Try this:
String xml = "<xml></xml>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(xml.getBytes()));
System.out.println(doc);

Categories