stax和dom

zazmityj  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(358)

我想编写一些代码,本质上类似于使用stax和dom读取一个大的xml文件,但是使用xmleventreader而不是xmlstreamreader(在继续创建dom之前,我需要能够检查一些元素的值)。
有没有人能举一个最简单的例子来说明这一点?到目前为止,我尝试的所有方法都会导致错误或空指针异常。
谢谢!爱洛

dauxcl2d

dauxcl2d1#

我也遇到了同样的问题,就我所能调试的而言,一切都表明jdk中有一个bug(至少在build1.8.0\u 162-b12上),更具体地说是在类中 com.sun.org.apache.xalan.internal.xsltc.trax.StAXEvent2SAX .
npe实际上只是另一个bug的结果,这个bug与在这个类中如何处理读取器有关 bridge() 方法。如果读者不在 START_DOCUMENT 状态下,下一个事件只会被窥视,而不会随着 nextEvent() 就在第一次。这导致了第一个问题 START_ELEMENT 要处理两次的事件。如果使用 StreamResult 而不是 DOMResult . 在那里,npe不会发生,但是结果流中生成的xml将包含第一个元素的标记开头两次。
我现在正试着用一个 XmlEventWriter 接收 DOMResult . 所以,基本上模拟 Transformer 将每个read事件直接推送到该writer。如果我成功了,我也会在这里发布我的解决方案。
ps:我想在jdk上报告这个问题,或者最终推动一个潜在的解决方案。如果有人能告诉我应该怎么做,我将非常感激。

更新:

所以,我用上面提到的方法解决了这个问题。基于使用stax和dom而不是使用 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编写器将遇到问题。如果您打算操纵这个dom,然后将它发送给另一个活动的 XMLEventWriter (正如我试图做的)使用 Transformer 再次,它将失败。这是因为 Transformer 将向已启动的写入程序发送开始文档事件。我也试过同样的方法。e。将节点 Package 到 DOMSource ,发送给另一个 XmlEventReader 把这些事情告诉我现有的 XmlEventWriter ,但这也不起作用 XmlEventReader 显然只支持 StreamSource s(见此处)。
总之,如果您只需要dom对象,这可能会很好地工作,但是如果您尝试将事件传递给编写器的xml片段进行转换(如我所做的),则可能会遇到问题。

smdncfj3

smdncfj32#

看看:http://www.vogella.com/articles/javaxml/article.html#javastax_read
它给出了一个如何使用xml流和xmleventreader的很好的小示例

相关问题