2012-02-05 3 views
8

Ho un oggetto XML e quando mi trasformo a stringa conCome si esegue il debug di un oggetto xml che causa un errore di trasformazione durante la scrittura nella stringa?

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 ""; 
} 

ottengo un errore con uno dei miei oggetti. Utilizzando un punto di interruzione e guardando attraverso l'oggetto xml non posso dire perché, sebbene TransformerException dica che l'eccezione contenuta è un'eccezione di puntatore nullo. Funziona su altri oggetti correlati che ho nello stesso programma ma non ho idea di come eseguire il debug di questo.

[[EDIT]] Ecco l'analisi dello stack:

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) 
+0

ho alcun problema quando uso il com.sun.org.apache.xml.internal. serialize.XMLSerializer, invece, fornisce avvertimenti sull'essere una API proprietaria del sole e può essere rimosso nelle versioni future – vextorspace

+0

Si prega di aggiungere la traccia dello stack completo in modo da rendere il problema più chiaro. Invece di ex.getMessage() fai ex.printStackTrace(). –

+0

La riga in cui viene attivato NPE è com.protocase.utils.StringHelpers.XMLElementToString (StringHelpers.java:132) È possibile sottolineare il metodo XMLElementToString in cui si trova la riga 132? Grazie – thermz

risposta

14

sto indovinando che l'errore è con uno dei tuoi oggetti, o perché l'oggetto non è XML valido o perché l'XML ha un nodo di testo vuoto (null) piuttosto che un valore di stringa vuoto.

vedere java.lang.NullPointerException

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

Basato sul link nel commento di @Sajan Chandran:

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

Se si dà un'occhiata a che si vedrà il codice.

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

Il problema essendo char.length() è zero a causa di un nodo di testo nullo.

Come afferma, per risolvere questo problema assicurarsi semplicemente che tutti i nodi XML abbiano un valore stringa anziché un valore 'null'.

Se ciò non funziona, è possibile pubblicare un esempio dell'oggetto XML che genera l'eccezione. Inoltre, puoi verificare che l'oggetto sia un XML valido e che le entità dei caratteri, ecc., Siano correttamente codificate.

+1

dovresti almeno includere il link alla fonte di questo suggerimento (che @SajanChandran ha fornito nel suo commento all'OP). – jtahlborn

+0

Scusa se l'ho aggiunto in una modifica dopo aver letto il link, ho perso l'url..pensava che fosse ovvio. Il mio punto principale era se si tratta di un oggetto specifico che causa l'errore, quindi è qualcosa di specifico su quell'oggetto, xml non valido, ecc. – Fraser

+0

Quindi il trasformatore non può gestire nodi di testo null? Che aspetto ha un nodo di testo null quando stai guardando l'xml? C'è un modo per rendere il trasformatore robusto a queste cose? – vextorspace

3

Sostanzialmente d'accordo con le altre risposte, ad eccezione di:

Il problema sarebbe di avere un nodo di testo con nullo (non vuoto) di contenuti di carattere, nel vostro doc o e struttura di dati.

Mentre il post di Kiran (collegato da Sajan) è utile, sono abbastanza sicuro che si sbaglia "il chars.length() era zero perché veniva tentato l'inserimento di un nodo di testo nullo." Il chars.length() non era zero; la chiamata a chars.length() ha generato un NPE perché chars era nullo.

Per trovare il problema, aggiungere una chiamata di metodo qui:

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 

Quindi definire checkForNullTextNodes(node) a: (pseudocodice)

  • passeggiata attraverso l'albero con n per ogni nodo
  • assegno ogni nodo di testo per dati carattere null

Per esempio. (Ancora semi-pseudocodice)

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

che dovrebbero aiutare a scoprire dove tutti i nodi di testo con contenuti carattere null sono, che dovrebbe aiutare a capire dove stanno venendo. Dove vengono create queste strutture doc o e?

+0

Penso che vuoto qui significhi nulla, cioè un nodo nella forma breve Fraser

+0

@Fraser, non sono sicuro di quale istanza di "vuoto" ci si riferisce. In quanto sopra quando dico "null" mi riferisco a un puntatore nullo, che non è un input valido per 'transformer.transform()'. Un elemento XML di breve formato come "" non dovrebbe mai generare un puntatore nullo durante l'analisi. – LarsH

+1

@Fraser, P.S., quando dico "vuoto" sopra mi riferisco a una stringa che è un oggetto reale (non nullo) ma contiene zero caratteri, ad esempio "" "'. – LarsH

3

Sono d'accordo con l'altra risposta, ecco il codice che ho usato per sbarazzarsi dei null nodi

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)); 
      } 
     } 
    } 
+1

Questo ha funzionato come un campione per me in realtà mi ha aiutato a trovare un errore nel mio xml. – Jeremy