How do you debug an xml object that causes a transform error when writing to string?

瘦欲@ 提交于 2019-12-13 12:03:15

问题


I have an XML Object and when I transform it to string with

public static String XMLElementToString(Document doc, Element e) {
    // --- Output XML ---
    try {
        TransformerFactory transFactory = TransformerFactory.newInstance();
        Transformer transformer = transFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

        StringWriter buffer = new StringWriter();
        Result result = new StreamResult(buffer);
        Source source = null;
        if (e != null) {
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            source = new DOMSource(e);
        } else {
            source = new DOMSource(doc);
        }
        transformer.transform(source, result); // <-- Error occurs here

        buffer.flush();
        return buffer.toString();

    } catch (TransformerException ex) {
        System.out.println("exception: " + ex.getMessage());            
    }
    return "";
}

I get an error with one of my objects. Using a breakpoint and looking through the xml object I cannot say why, although the TransformerException does say that the contained exception is a null pointer exception. It works on other related objects I have in the same program but I have no idea how to debug this.

[[EDIT]] Here is the stack trace:

ERROR:  ''
javax.xml.transform.TransformerException: java.lang.NullPointerException
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:716)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:313)
at com.protocase.utils.StringHelpers.XMLElementToString(StringHelpers.java:132)
at com.protocase.io.PDWriter.writePD(PDWriter.java:49)
at com.protocase.io.PDWriter.writePDA(PDWriter.java:26)
at com.protocase.viewer.JDesigner.OnSaveAs(JDesigner.java:1364)
at com.protocase.viewer.JDesigner.access$000(JDesigner.java:106)
at com.protocase.viewer.JDesigner$34.actionPerformed(JDesigner.java:722)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6288)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6053)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
at com.protocase.viewer.EventQueueProxy.dispatchEvent(JDesigner.java:2338)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Caused by: java.lang.NullPointerException
at com.sun.org.apache.xml.internal.serializer.ToUnknownStream.characters(ToUnknownStream.java:338)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:240)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:226)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:226)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:226)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:226)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:132)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:94)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:661)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:707)
    ... 45 more
---------
java.lang.NullPointerException
at com.sun.org.apache.xml.internal.serializer.ToUnknownStream.characters(ToUnknownStream.java:338)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:240)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:226)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:226)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:226)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:226)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:132)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:94)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:661)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:707)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:313)
at com.protocase.utils.StringHelpers.XMLElementToString(StringHelpers.java:132)
at com.protocase.io.PDWriter.writePD(PDWriter.java:49)
at com.protocase.io.PDWriter.writePDA(PDWriter.java:26)
at com.protocase.viewer.JDesigner.OnSaveAs(JDesigner.java:1364)
at com.protocase.viewer.JDesigner.access$000(JDesigner.java:106)
at com.protocase.viewer.JDesigner$34.actionPerformed(JDesigner.java:722)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6288)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6053)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at     java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
at com.protocase.viewer.EventQueueProxy.dispatchEvent(JDesigner.java:2338)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

回答1:


I am guessing that the error is with one of your objects, either because that object is not valid XML or because the XML has an empty (null) text node rather than an empty string value.

see java.lang.NullPointerException

at com.sun.org.apache.xml.internal.serializer. ToUnknownStream.characters(ToUnknownStream.java:338)

Based on the link in @Sajan Chandran's comment:

http://dotcommers.wordpress.com/2008/10/22/javaxxmltransformtransformerexception-javalangnullpointerexception-how-to-solve/

If you take a look at that you will see the code.

public void characters(String chars) throws SAXException
{
  final int length = chars.length();

The issue being char.length() is zero because of a null text node.

As it states, to fix this simply make sure all XML nodes have a string value rather than 'null' value.

If this does not work can you post an example of the XML object that causes the exception to be thrown. Also, can you check that the object is valid XML and that character entities, etc, are properly encoded.




回答2:


Basically agreeing with the other answers, except:

The problem would be that you have a text node with null (not empty) character content, in your doc or e data structure.

While Kiran's post (linked by Sajan) is helpful, I'm pretty sure he's mistaken about "the chars.length() was zero because there was a null text node insertion being tried." The chars.length() was not zero; the call to chars.length() threw an NPE because chars was null.

To find the problem, add a method call here:

    if (e != null) {
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        source = new DOMSource(e);
        checkForNullTextNodes(e); // ADDED
    } else {
        source = new DOMSource(doc);
        checkForNullTextNodes(doc);  // ADDED
    }
    transformer.transform(source, result); // <-- Error occurs here

Then define checkForNullTextNodes(node) to: (pseudocode)

  • walk through the tree with n for each node
  • check each text node for null character data

E.g. (still semi-pseudocode)

 if (n.getType() == org.w3c.dom.Node.TEXT_NODE && n.getNodeValue() == null) {
     throw new Exception("Text node with null content: " +
         path to this node);
 }

That should help you find out where any text nodes with null character content are, which should help you figure out where they are coming from. Where are these doc or e structures being created, anyway?




回答3:


I agree with the other answer, here is the code I used to get rid of the null nodes

public void deleteNullNode(Node racine)
    {
        NodeList nl = racine.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++)
        {
            if (nl.item(i).getNodeType() == Node.TEXT_NODE && nl.item(i).getNodeValue() == null)
            {
                nl.item(i).getParentNode().removeChild(nl.item(i));
            }
            else
            {
                deleteNullNode(nl.item(i));
            }
        }
    }


来源:https://stackoverflow.com/questions/9150403/how-do-you-debug-an-xml-object-that-causes-a-transform-error-when-writing-to-str

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!