1

I am using this code to write a (simple) DOM tree to a string, but on my LG Optimus L3, this takes up to 30 seconds or more. How could I make it faster?

Transformer t = TransformerFactory.newInstance().newTransformer();

transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
t.transform(new DOMSource(doc), new StreamResult(writer));
result = writer.getBuffer().toString();
Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195
  • Usually, and sometimes, `XXXFactorty.newInstance()` is very expensive. You may cache the instance and re-use it. – Jin Kwon May 08 '14 at 14:32
  • @JinKwon yes, creating the instance takes considerable time, around 2 seconds. The main problem really lies in the `transform` call though, which takes 30 seconds (!) or more. – Bart Friederichs May 08 '14 at 14:35
  • Maybe eclipse attached? http://stackoverflow.com/a/15097479/330457 – Jin Kwon May 08 '14 at 14:40
  • I assume you already parsed the `doc` before measuring the time. Or check this out. http://stackoverflow.com/a/4799242/330457 – Jin Kwon May 08 '14 at 14:42
  • @JinKwon Without eclipse, it's a lot faster. I hate this slow debugging though. And the `doc` is created in the app, it's the reply of another call. – Bart Friederichs May 08 '14 at 14:42
  • @JinKwon do you perhaps know if this also applies to the use of XPath? – Bart Friederichs May 08 '14 at 15:08
  • I'm not sure `XSLT` is wired with `XPath` internally or not. I hope you find the solution and share with us. – Jin Kwon May 08 '14 at 15:14

1 Answers1

0

I ended up just writing my own serializer. It certainly doesn't support everything, just tag names, attributes and text content, but it is simple and fast:

void write(Node e, StringWriter w) {
    if (e.getNodeType() == Node.ELEMENT_NODE) {
        w.write("<"+e.getNodeName());
        if (e.hasAttributes()) {
            NamedNodeMap attrs = e.getAttributes();
            for (int i = 0; i < attrs.getLength(); i++) {
                w.write(" "+attrs.item(i).getNodeName()+"=\""+
                       attrs.item(i).getNodeValue()+"\"");              
            }
        }
        w.write(">");

        if (e.hasChildNodes()) {
            NodeList children = e.getChildNodes();
            for (int i = 0; i < children.getLength(); i++) {
                write(children.item(i), w);
            }

        }
        w.write("</"+e.getNodeName()+">");
    }
    if (e.getNodeType() == Node.TEXT_NODE) {
        w.write(e.getTextContent());
    }
}

You use it with a Document like this:

StringWriter writer = new StringWriter();
String result;

write(doc.getDocumentElement(), writer);
result = writer.getBuffer().toString();
Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195