簡體   English   中英

SAXParser無法正確地將org.w3c.dom.Document轉換為java.io.InputStream

[英]org.w3c.dom.Document conversion to java.io.InputStream not read properly by SAXParser

我正在使用以下代碼使用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();
    }

解析文檔后,我收到錯誤消息

Line 1: Document root element 'MyRootName' must match DOCTYPE root 'null'.

如果我只是解析xmlDocument所基於的xmlFile ,那么一切都很好。

我已經確保了XMLDOCUMENT被初始化和有效的,我甚至試圖通過xmlDocument.getDocumentElement()DOMSource ,我也保證了是有效的,什么我期待它是(即文檔的根節點其名稱正確)

為什么javax.xml.parsers.SAXParser不能以與從文件系統讀取xmlFile相同的方式讀取java.io.InputStream

編輯

相關問題(我嘗試了所有這些解決方案都無濟於事): 如何從文檔或節點創建InputStream

我已經找到了原因,在這里進行了詳細說明: 使用DOM解析xml,刪除了DOCTYPE

所以問題不在parser ,而是在XML中刪除<!DOCTYPE ...>行的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文件的直接路徑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM