我正在使用woodstox为
XML文件实现StAX解析器.假设我的文件系统中的公共目录中有一个匹配DTD的有效XML文件.
/path/to/test.xml /path/to/test.dtd
XML使用相对系统标识符声明引用其DTD,如下所示:
<!DOCTYPE test SYstem "test.dtd">
从验证的角度来看,一切似乎都很好. (是吗?xmllint不会抱怨.)但是,当我尝试使用下面的代码解析文件时,woodstox会抛出java.io.FileNotFoundException,因为它无法找到相对的DTD文件.在我看来,实现尝试相对于工作目录而不是相对于XML文件对象访问DTD文件.
import java.io.FileInputStream; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamReader; public class Test { public static void main( String[] args ) throws Exception { FileInputStream fileInputStream = new FileInputStream( args[0] ); XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory(); XMLStreamReader xsr = xmlInputFactory.createXMLStreamReader(fileInputStream); while( xsr.hasNext() ) { if( xsr.next() == XMLStreamConstants.DTD ) { System.err.println( xsr.getText() ); } } } }
您将需要提供自己的
XMLResolver
接口实现(在SAX世界中称为
EntityResolver)以帮助解析器找到DTD. XMLInputFactory具有setXMLResolver()方法,可以为您完成.
有关该主题的更多信息:
> XML Entity and URI Resolvers
在解析器需要解析SYstem URI时,了解一下究竟发生了什么,这也是一个好主意.例如,woodstox有an internal (and a default) implementation of the XMLResolver
(以及a proxy between the SAX’s EntityResolver
and a StAX XMLResolver
).看看它对DTD“文件名”的作用,你会发现它为什么会这样运作.