我有String数据的XML数据,我想将其转换为XML文档,以便在其中进行一些处理,并且我使用以下方法来实现:
private Document convert(String xml) throws ParserConfigurationException,
SAXException, IOException {
// convert String into InputStream
InputStream is = new ByteArrayInputStream(xml.getBytes());
// convert InputStream to Document
domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
builder = domFactory.newDocumentBuilder();
builder(builder); // this is the error handler method i'm using
Document doc = builder.parse(is);
is.close();
return doc;
}
奇怪的是,处理过程正确完成并且每件事情都很完美我的结果,但另一方面,当我进行转换过程时,我在控制台中收到了一条消息:
[Fatal Error] :1:1: Premature end of file.
所以,我使用了一个错误处理程序来捕获该致命错误并打印异常堆栈跟踪,然后我抛出了这些异常:
org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Premature end of file.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
at com.nc.inotify.dp.xml.impl.XmlSource.convert(XmlSource.java:327)
at com.nc.inotify.dp.xml.impl.XmlSource.update(XmlSource.java:299)
at com.nc.inotify.dp.xml.junit.TXmlSource.testUpdate(TXmlSource.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
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)
更新 XML文件:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" version="2.0">
<channel>
<title>Yahoo! Weather - Sunnyvale, CA</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html</link>
<description>Yahoo! Weather for Sunnyvale, CA</description>
<language>en-us</language>
<lastBuildDate>Thu, 06 Jun 2013 1:56 am PDT</lastBuildDate>
<ttl>60</ttl>
<yweather:location city="Sunnyvale" country="United States" region="CA"/>
<yweather:units distance="mi" pressure="in" speed="mph" temperature="F"/>
<yweather:wind chill="58" direction="30" speed="3"/>
<yweather:atmosphere humidity="81" pressure="29.96" rising="2" visibility="10"/>
<yweather:astronomy sunrise="5:46 am" sunset="8:25 pm"/>
<image>
<title>Yahoo! Weather</title>
<width>142</width>
<height>18</height>
<link>http://weather.yahoo.com</link>
<url>http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif</url>
</image>
<item>
<title>Conditions for Sunnyvale, CA at 1:56 am PDT</title>
<geo:lat>37.37</geo:lat>
<geo:long>-122.04</geo:long>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html</link>
<pubDate>Thu, 06 Jun 2013 1:56 am PDT</pubDate>
<yweather:condition code="26" date="Thu, 06 Jun 2013 1:56 am PDT" temp="58" text="Cloudy"/>
<description><![CDATA[
<img src="http://l.yimg.com/a/i/us/we/52/26.gif"/><br />
<b>Current Conditions:</b><br />
Cloudy, 58 F<BR />
<BR /><b>Forecast:</b><BR />
Wed - Partly Cloudy. High: 70 Low: 55<br />
Thu - AM Clouds/PM Sun. High: 74 Low: 57<br />
Fri - Partly Cloudy. High: 81 Low: 62<br />
Sat - Sunny. High: 78 Low: 63<br />
Sun - Partly Cloudy. High: 72 Low: 60<br />
<br />
<a href="http://us.rd.yahoo.com/dailynews/rss/weather/Sunnyvale__CA/*http://weather.yahoo.com/forecast/USCA1116_f.html">Full Forecast at Yahoo! Weather</a><BR/><BR/>
(provided by <a href="http://www.weather.com" >The Weather Channel</a>)<br/>
]]></description>
<yweather:forecast code="29" date="5 Jun 2013" day="Wed" high="70" low="55" text="Partly Cloudy"/>
<yweather:forecast code="30" date="6 Jun 2013" day="Thu" high="74" low="57" text="AM Clouds/PM Sun"/>
<yweather:forecast code="30" date="7 Jun 2013" day="Fri" high="81" low="62" text="Partly Cloudy"/>
<yweather:forecast code="32" date="8 Jun 2013" day="Sat" high="78" low="63" text="Sunny"/>
<yweather:forecast code="30" date="9 Jun 2013" day="Sun" high="72" low="60" text="Partly Cloudy"/>
<guid isPermaLink="false">USCA1116_2013_06_09_7_00_PDT</guid>
</item>
</channel>
</rss><!-- api10.weather.ch1.yahoo.com Thu Jun 6 09:34:11 PST 2013 -->
答案 0 :(得分:0)
如何通过创建一个单独的类来使这个私有方法可测试?让我们从测试开始:
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class StringToDOMConverterTest {
private StringToDOMConverter stringToDOMConverter = new StringToDOMConverter();
@Test
public void converterShouldConvertSimpleDocument() throws Exception {
final Document dom = stringToDOMConverter.convert("<mail><to>Alice</to><from>Jum</from><heading>Invitation</heading><body>Let's get some icecream!</body></mail>");
final Element documentRoot = dom.getDocumentElement();
assertThat(documentRoot.getNodeName(), is("mail"));
}
}
现在是方法的修改版本(构建器语句未编译):
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class StringToDOMConverter {
private final DocumentBuilderFactory domFactory;
private DocumentBuilder builder;
public StringToDOMConverter() {
domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(false);
}
public Document convert(final String xml) throws ParserConfigurationException, SAXException, IOException {
final InputStream is = new ByteArrayInputStream(xml.getBytes());
Document document = null;
try {
builder = domFactory.newDocumentBuilder();
// builder(builder); // this is the error handler method i'm using
document = builder.parse(is);
} finally {
if(is != null) is.close();
}
return document;
}
}
这是一个可以尝试所有标志和错误处理内容的基础。不要忘记需要检查前置条件并适当地处理错误(并为此编写测试... :-))。
答案 1 :(得分:0)
您的xml不是格式良好的xml。如果您在浏览器中打开它,您可以看到它没有正确打开。您可以使用以下位置提供的xml验证程序验证xml:
http://www.w3schools.com/xml/xml_validator.asp
修复你的xml,你应该很好。