2011-08-31 75 views
4

我想重用我们代码库中的一些现有代码,它接受XMLStreamReader我的应用程序将所需数据作为w3c文档。将Java w3c文档转换为XMLStreamReader

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

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的答案。

+0

是它试图下载的XSD? – sje397

+0

nope..xml是或多或少你有什么: Wibble

+0

只是头脑风暴。你不应该在createXMLStreamReader中使用source.getSystemId()吗? – dierre

回答

2

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

随着撒克逊人,你也可以短路的使用的东西的东西XQuery的侧像

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

但我认为XQJ方法是清洁剂。

+0

为工作四处满分 –

1

对我来说,DOMSource不是StreamSource的一个实例,所以它已被踢出。

1

我的务实解决方案使用ByteArrayOutputStream文档到byte阵列再喂,早在使用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())); 

它不漂亮,但它的作品一直以输出。

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> 

但是,这是使用以下代码

+0

它不仅是unpretty,它还涉及连载和重新分析这可能是在时间非常昂贵的文件和内存使用情况。 –

1

我遇到同样的错误(视窗7/Oracle的JDK 7)一个讨厌的解决方案。