2012-04-27 17 views
60

Quiero convertir un objeto org.w3c.dom.Document en una Cadena. Estoy usando Java 6 y estoy abierto a usar cualquier tecnología (completamente gratuita) que esté a la altura de la tarea. Probé la solución de este hilo - Is there a more elegant way to convert an XML Document to a String in Java than this code?, donde tienen¿Cómo convierto un objeto org.w3c.dom.Document en una Cadena?

DOMImplementationLS domImplementation = (DOMImplementationLS) doc.getImplementation(); 
LSSerializer lsSerializer = domImplementation.createLSSerializer(); 
String html = lsSerializer.writeToString(doc); 

pero fue recibido con la siguiente excepción horrendo ...

org.w3c.dom.DOMException: DOM method not supported 
    at org.w3c.tidy.DOMDocumentImpl.getImplementation(DOMDocumentImpl.java:129) 
    at com.myco.myproj.cleaners.JTidyCleaner.outputDocAsString(JTidyCleaner.java:74) 
    at com.myco.myproj.cleaners.JTidyCleaner.parse(JTidyCleaner.java:63) 
    at com.myco.myproj.util.NetUtilities.getUrlAsDocument(NetUtilities.java:51) 
    at com.myco.myproj.parsers.AbstractHTMLParser.getEventFromElement(AbstractHTMLParser.java:131) 
    at com.myco.myproj.parsers.AbstractHTMLParser.parsePage(AbstractHTMLParser.java:100) 
    at com.myco.myproj.parsers.AbstractHTMLParser.getEvents(AbstractHTMLParser.java:63) 
    at com.myco.myproj.domain.EventFeed.refresh(EventFeed.java:87) 
    at com.myco.myproj.domain.EventFeed.getEvents(EventFeed.java:72) 
    at com.myco.myproj.parsers.impl.ChicagoCouncilGlobalAffairsParserTest.testParser(ChicagoCouncilGlobalAffairsParserTest.java:21) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) 
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
+0

transformación de identidad (http://en.wikipedia.org/wiki/Identity_transform) es su mejor opción si no desea depender de algún tipo de serializador. Las dos respuestas que se han dado ya hacen precisamente eso. La ejecución de una transformación vacía como esa hace que la identidad se transforme detrás de las escenas. –

Respuesta

61

Si está bien hacer la transformación, puedes probar esto.

DocumentBuilderFactory domFact = DocumentBuilderFactory.newInstance(); 
DocumentBuilder builder = domFact.newDocumentBuilder(); 
Document doc = builder.parse(st); 
DOMSource domSource = new DOMSource(doc); 
StringWriter writer = new StringWriter(); 
StreamResult result = new StreamResult(writer); 
TransformerFactory tf = TransformerFactory.newInstance(); 
Transformer transformer = tf.newTransformer(); 
transformer.transform(domSource, result); 
System.out.println("XML IN String format is: \n" + writer.toString()); 
+0

¿Alguna idea de cómo escribir JUnits para el código anterior? Obtengo un verifyError mientras escribo lo mismo. He hecho una pregunta en SO, si estás disponible, responde amablemente. https://stackoverflow.com/q/48560458/5989309 –

68

uso algo como

import java.io.*; 
import javax.xml.transform.*; 
import javax.xml.transform.dom.*; 
import javax.xml.transform.stream.*; 

//method to convert Document to String 
public String getStringFromDocument(Document doc) 
{ 
    try 
    { 
     DOMSource domSource = new DOMSource(doc); 
     StringWriter writer = new StringWriter(); 
     StreamResult result = new StreamResult(writer); 
     TransformerFactory tf = TransformerFactory.newInstance(); 
     Transformer transformer = tf.newTransformer(); 
     transformer.transform(domSource, result); 
     return writer.toString(); 
    } 
    catch(TransformerException ex) 
    { 
     ex.printStackTrace(); 
     return null; 
    } 
} 
+0

funciona, pero ¿cómo hacerlo bonito imprimir: s –

+14

@MubasharAhmad 'transformer.setOutputProperty (OutputKeys.INDENT," yes ");' –

1

Una versión de Scala basada en la respuesta de Zaz.

case class DocumentEx(document: Document) { 
    def toXmlString(pretty: Boolean = false):Try[String] = { 
     getStringFromDocument(document, pretty) 
    } 
    } 

    implicit def documentToDocumentEx(document: Document):DocumentEx = { 
    DocumentEx(document) 
    } 

    def getStringFromDocument(doc: Document, pretty:Boolean): Try[String] = { 
    try 
    { 
     val domSource= new DOMSource(doc) 
     val writer = new StringWriter() 
     val result = new StreamResult(writer) 
     val tf = TransformerFactory.newInstance() 
     val transformer = tf.newTransformer() 
     if (pretty) 
     transformer.setOutputProperty(OutputKeys.INDENT, "yes") 
     transformer.transform(domSource, result) 
     Success(writer.toString); 
    } 
    catch { 
     case ex: TransformerException => 
     Failure(ex) 
    } 
    } 

Con esto, se puede hacer ya sea doc.toXmlString() o llamar a la función getStringFromDocument(doc).

Cuestiones relacionadas