SAXParser无法正确读取org.w3c.dom.Document到java.io.InputStream的转换
我使用下面的代码用SAXParser无法正确读取org.w3c.dom.Document到java.io.InputStream的转换,java,dom,sax,Java,Dom,Sax,我使用下面的代码用javax.xml.parsers.SAXParser解析org.w3c.dom.Document try { // --- Prepare our SAX parser --- SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(true); SAXParser parser = factory.
javax.xml.parsers.SAXParser
解析org.w3c.dom.Document
try
{
// --- Prepare our SAX parser ---
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
SAXParser parser = factory.newSAXParser();
// parser.parse(xmlFile, xmlValidator); /* Does not validate unsaved changes */
// --- Create a stream form our already parsed xml document ---
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Source xmlSource = new DOMSource(xmlDocument);
Result outputTarget = new StreamResult(outputStream);
TransformerFactory.newInstance().newTransformer().transform(xmlSource, outputTarget);
// --- Validate the xmlDocument ---
parser.parse(new ByteArrayInputStream(outputStream.toByteArray()), xmlValidator);
}
catch (ParserConfigurationException | SAXException | TransformerException | TransformerFactoryConfigurationError | IOException e)
{
e.printStackTrace();
}
解析文档时,我会收到错误消息
第1行:文档根元素“MyRootName”必须与DOCTYPE root“null”匹配。
如果我只是解析xmlDocument
所基于的xmlFile
,那么一切都很正常
我已经确保xmlDocument已初始化且有效,我甚至尝试将xmlDocument.getDocumentElement()
传递到DOMSource
,我也已经确保它是有效的,并且是我期望的(即具有正确名称的文档根节点)
为什么javax.xml.parsers.SAXParser
读取java.io.InputStream
的方式与从文件系统读取“xmlFile”的方式不同
编辑
相关问题(我已尝试了所有这些解决方案,但均无效):
我已经找到了原因,详情如下:
因此问题不在于
解析器,而在于转换器,它剥离了XML中的
行。要解决这个问题,只需设置transformer属性,使其包含DTD文件
// --- Create a transformer and transform our Document into an InputStream ---
Transformer transformer = TransformerFactory.newInstance().newTransformer();
// By default the transformer strips out the DOCTYPE tag so we must re-add our DTD file declaration
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, xmlFile.getParent() + "\\" + xmlDocument.getDoctype().getSystemId());
transformer.transform(xmlSource, outputTarget);
如果您只是传入DTD文件名,解析器将在程序启动的位置搜索它,建议指定DTD文件的直接路径,如上所述