2012-04-27 161 views
60

我想將org.w3c.dom.Document對象轉換爲String。我正在使用Java 6,並願意使用任何完全免費的技術。我想從這個線程解決方案 - Is there a more elegant way to convert an XML Document to a String in Java than this code?,他們有如何將org.w3c.dom.Document對象轉換爲字符串?

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

,但有以下異常可怕迎了上去......

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

身份轉換(http://en.wikipedia.org/wiki/Identity_transform)是你最好的選擇,如果你不想依賴某種序列化器。已經給出的兩個答案已經做到了。像這樣運行一個空的轉換,會在幕後轉換身份。 – 2012-04-27 19:11:04

回答

61

如果您可以做轉換,你可以試試這個。

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

任何想法如何編寫上述代碼的JUnits?編寫相同的代碼時,我得到一個verifyError錯誤。我在SO中提出了一個問題,如果你有問題,請回答。 https://stackoverflow.com/q/48560458/5989309 – 2018-02-01 12:17:02

68

使用某些東西一樣

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

它的工作原理,但如何做漂亮打印:s – 2014-06-13 04:22:34

+14

@MubasharAhmad'transformer.setOutputProperty(OutputKeys.INDENT,「yes」);' – 2015-05-05 13:28:00

1

一個基於Zaz的答案的Scala版本。

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) 
    } 
    } 

有了這一點,你可以做任何doc.toXmlString()或致電getStringFromDocument(doc)功能。