我想在我们的代码库中重用一些现有代码,该代码库接受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的实际内容来转换的。
更新:我上面的orignal测试用例实际上是使用我的项目类路径运行的,它实际上包含了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的答案。
答案 0 :(得分:2)
这有点令人费解,但任何支持XQJ API的XQuery实现(例如Saxon)都允许您提供DOM作为查询“。”的输入,并将结果作为XMLStreamReader获取。虽然涉及很多重量级机械,但它应该是完全有效的。
使用Saxon,您还可以使用类似
之类的东西来缩短XQuery方面的内容Document doc; // the DOM document
XMLStreamReader reader = new PullToStax(PullProvider.makePullProvider(new DocumentWrapper(doc));
但我认为XQJ方法更清晰。
答案 1 :(得分:1)
我觉得DOMSource
不是StreamSource
的实例,所以它会被踢出去。
答案 2 :(得分: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()));
它不漂亮但它有效。
答案 3 :(得分: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>
但这也是一个令人讨厌的解决方案。
答案 4 :(得分:1)
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);