6

我想在我们的代码库中重用一些现有代码,这些代码接受XMLStreamReader我的应用程序具有所需数据作为 w3c 文档。

下面的例子是一个最小的测试用例:

public static void main(String[] args) throws Exception {
    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = builderFactory.newDocumentBuilder();

    Document doc = builder.newDocument();

    Element rootElement = doc.createElement("Groups");
    doc.appendChild(rootElement);
    Element group = doc.createElement("Group");
    group.setTextContent("Wibble");
    rootElement.appendChild(group);

    DOMSource source = new DOMSource(doc);

    XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(source);

    reader.nextTag();
    System.out.println("NextTag:" + reader.getName());
}

预期的输出应该是这样的:NextTag:Groups但是会抛出以下内容:

Exception in thread "main" javax.xml.stream.XMLStreamException: java.net.MalformedURLException
    at com.sun.xml.stream.XMLReaderImpl.setInputSource(XMLReaderImpl.java:196)
    at com.sun.xml.stream.XMLReaderImpl.<init>(XMLReaderImpl.java:179)
    at com.sun.xml.stream.ZephyrParserFactory.createXMLStreamReader(ZephyrParserFactory.java:139)
    at Main.main(Main.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.net.MalformedURLException
    at java.net.URL.<init>(URL.java:601)
    at java.net.URL.<init>(URL.java:464)
    at java.net.URL.<init>(URL.java:413)
    at com.sun.xml.stream.XMLEntityManager.startEntity(XMLEntityManager.java:762)
    at com.sun.xml.stream.XMLEntityManager.startDocumentEntity(XMLEntityManager.java:697)
    at com.sun.xml.stream.XMLDocumentScannerImpl.setInputSource(XMLDocumentScannerImpl.java:300)
    at com.sun.xml.stream.XMLReaderImpl.setInputSource(XMLReaderImpl.java:193)
    ... 8 

当前使用 Java 6 更新 22。

更多信息:ZephyrParserFactory#jaxpSourcetoXMLInputSource的来源似乎表明 Source 对象是通过处理它SystemId而不是 DOMSource 的实际内容来转换的。

更新:我上面的原始测试用例实际上是使用我的项目类路径运行的,该类路径实际上包括 JAXB 2.2.1 库,而后者又引入了 sjsxp 1.0.1。在干净的类路径上运行会产生:

Exception in thread "main" java.lang.UnsupportedOperationException: Cannot create XMLStreamReader or XMLEventReader from a javax.xml.transform.dom.DOMSource
    at com.sun.xml.internal.stream.XMLInputFactoryImpl.jaxpSourcetoXMLInputSource(XMLInputFactoryImpl.java:302)
    at com.sun.xml.internal.stream.XMLInputFactoryImpl.createXMLStreamReader(XMLInputFactoryImpl.java:145)

这符合@Gary Rowe 的回答。

4

5 回答 5

2

这有点令人费解,但任何支持 XQJ API(例如 Saxon)的 XQuery 实现都将允许您提供一个 DOM 作为查询“.”的输入,并以 XMLStreamReader 的形式获得结果。尽管涉及很多重量级机器,但它应该非常高效。

使用 Saxon,您还可以使用类似的东西短路 XQuery 方面

Document doc; // the DOM document
XMLStreamReader reader = new PullToStax(PullProvider.makePullProvider(new DocumentWrapper(doc));

但我认为 XQJ 方法更清洁。

于 2011-08-31T14:34:32.713 回答
2

Woodstox 的 WstxDOMWrappingReader 类提供了您所需要的内容。请参阅https://fasterxml.github.io/woodstox/javadoc/5.0/com/ctc/wstx/dom/WstxDOMWrappingReader.html上的 Javadoc

小例子:

  DOMSource domSource = new DOMSource(node);
  ReaderConfig config = ReaderConfig.createFullDefaults();
  XMLStreamReader reader = WstxDOMWrappingReader.createFrom(domSource, config);
于 2016-03-15T10:11:54.107 回答
1

在我看来, aDOMSource不是 a 的实例,StreamSource因此它被踢出。

于 2011-08-31T14:15:37.340 回答
1

我务实的解决方案是使用将文档输出到byte数组ByteArrayOutputStream,然后使用ByteArrayInputStream

Transformer xformer = TransformerFactory.newInstance().newTransformer();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
StreamResult out = new StreamResult(outputStream);
xformer.transform(source, out);
reader = xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(outputStream.toByteArray()));

它不漂亮,但它有效。

于 2011-09-01T07:54:13.670 回答
1

我使用以下代码遇到了同样的错误(Windows 7/Oracle JDK 7):

DOMSource domSource = new DOMSource(element);
XMLEventReader parser = XMLInputFactory.newInstance().createXMLEventReader(domSource);

我通过添加一个新的 Woodstox 依赖项来修复它:

<dependency>
    <groupId>org.codehaus.woodstox</groupId>
    <artifactId>woodstox-core-lgpl</artifactId>
    <version>4.1.5</version>
</dependency>

但这也是一个讨厌的解决方案。

于 2013-10-13T16:42:05.337 回答