![](/img/trans.png)
[英]Unable to check CDATA in XML using XMLEventReader in Stax
[英]StAX and DOM using XMLEventReader rather than XMLStreamReader
我想编写一些类似于使用stax和dom读取大XML文件的代码,但使用XMLEventReader而不是XMLStreamReader(我需要能够检查某些元素的值,然后再创建DOM)。
有没有人有一个最小的例子,这看起来如何? 到目前为止,我尝试过的所有操作都会给我带来错误或Null Pointer Exception。
谢谢! 阿罗
看看: http : //www.vogella.com/articles/JavaXML/article.html#javastax_read
它给出了一个很好的小示例,说明如何使用xml流和XMLEventReader
我遇到了同样的问题,据我所知,一切都表明JDK中存在一个错误(至少在内部版本1.8.0_162-b12上),更具体地说是在com.sun.org.apache.xalan.internal.xsltc.trax.StAXEvent2SAX
类中com.sun.org.apache.xalan.internal.xsltc.trax.StAXEvent2SAX
。
NPE实际上只是另一个错误的结果,该错误与在此类的bridge()
方法中如何处理阅读器有关。 如果读者不在START_DOCUMENT
状态,则仅在下一次事件被START_DOCUMENT
,而第一次没有使用nextEvent()
进行下一个事件。 这导致第一个START_ELEMENT
事件被处理两次。 如果使用StreamResult
而不是DOMResult
则可以很好地观察到这DOMResult
。 在那里不会发生NPE,但是在结果流中生成的XML将两次包含第一个元素的标签的开头。
我现在正在尝试使用接收DOMResult
的XmlEventWriter
来解决此DOMResult
。 因此,基本上模拟了Transformer
功能,将每个读取事件直接推给该编写器。 如果我成功了,我也将在这里发布我的解决方案。
PS:我想在JDK上报告此问题,或者最终甚至提出潜在的解决方案。 如果有人能告诉我应该怎么做,我将非常感谢。
因此,我设法通过上述方法解决了这个问题。 根据使用stax和dom读取大型XML文件中建议的代码,而不是使用Transformer
,可以使用以下方法:
private Node readToNode(final XMLEventReader reader) throws XMLStreamException, ParserConfigurationException {
XMLEvent event = reader.peek();
if (!event.isStartElement()) {
throw new IllegalArgumentException("reader must be on START_ELEMENT event");
}
final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
final XMLEventWriter writer = XMLOutputFactory.newInstance().createXMLEventWriter(new DOMResult(document));
int depth = 0;
do {
event = reader.nextEvent();
writer.add(event);
if (event.isStartElement()) {
depth++;
} else if (event.isEndElement()) {
depth--;
}
} while (reader.hasNext() && !(event.isEndElement() && depth <= 0));
return document.getDocumentElement();
}
但是,这种方法有一些局限性 ! 在代码中可见,我们需要创建一个包装该节点的Document
对象,否则XML writer将遇到问题。 如果您打算操纵此DOM,然后再使用Transformer
将其发送到另一个活动的XMLEventWriter
(如我所尝试的那样),它将失败。 这是因为Transformer
会将START_DOCUMENT事件发送给已经开始的编写器。 我想同样的方法倒过来,即包裹节点为DOMSource
,其发送给其他XmlEventReader
和管道的事件,以我现有的XmlEventWriter
,但也不能按XmlEventReader
显然只支持StreamSource
S(参见这里 ) 。
总而言之,如果只需要DOM对象,这可能会很好地工作,但是如果您试图将传递事件的XML片段转换为writer(就像我所做的那样),则可能会遇到问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.