到目前为止,这是一个失败的故事,任何建议都是值得欢迎的。我尝试了以下几点:
使用JAXP与撒克逊一起使用XMLStreamReader编写文档
守则:
JSONObject obj = new JSONObject("{\"alice\":{\"bob\": \"a\"}}");
AbstractXMLStreamReader reader = new MappedXMLStreamReader(obj);
StAXSource source = new StAXSource(reader);
Document document = XMLUtils.createDocument();
DOMResult result = new DOMResult(document);
Transformer identity = TransformerUtils.getIdentityTransformer();
identity.transform(source, result);
result.getNode();这是因为我们使用的撒克逊转换器不支持StAXSource,所以失败了。例外是:
org.orbeon.saxon.trans.DynamicError: A source of type javax.xml.transform.stax.StAXSource is not supported in this environment
org.orbeon.saxon.event.Sender.send(Sender.java:185)
org.orbeon.saxon.IdentityTransformer.transform(IdentityTransformer.java:29)
org.orbeon.oxf.xml.TransformerWrapper.transform(TransformerUtils.java:597)
org.apache.jsp.gaga_jsp._jspService(gaga_jsp.java:93)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)使用JAXP和XMLStreamReader编写文档
守则:
JSONObject obj = new JSONObject("{\"alice\":{\"bob\": \"a\"}}");
AbstractXMLStreamReader reader = new MappedXMLStreamReader(obj);
StAXSource source = new StAXSource(reader);
Document document = XMLUtils.createDocument();
DOMResult result = new DOMResult(document);
Transformer identity = orbeon.apache.xalan.processor.TransformerFactoryImpl.newInstance().newTransformer();
identity.transform(source, result);
result.getNode();这在Xalan2.5.1(我们使用的版本)中失败了。最新的版本是2.7.1,也许他们在该版本中增加了对StAXSource的支持。
javax.xml.transform.TransformerException: Can't transform a Source of type javax.xml.transform.stax.StAXSource
orbeon.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:372)
org.apache.jsp.gaga_jsp._jspService(gaga_jsp.java:82)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)使用XMLStreamReader和DOMResult编写文档
守则:
JSONObject obj = new JSONObject("{\"alice\":{\"bob\": \"a\"}}");
AbstractXMLStreamReader streamReader = new MappedXMLStreamReader(obj);
XMLInputFactory readerFactory = XMLInputFactory.newInstance();
XMLEventReader eventReader = readerFactory.createXMLEventReader(streamReader);
Document document = XMLUtils.createDocument();
DOMResult result = new DOMResult(document);
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLEventWriter eventWriter = outputFactory.createXMLEventWriter(result);
eventWriter.add(eventReader);
eventWriter.close();
result.getNode();这一条导致了Xerces中的NPE:
java.lang.NullPointerException
orbeon.apache.xerces.dom.CoreDocumentImpl.setXmlVersion(CoreDocumentImpl.java:850)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
com.sun.xml.internal.stream.writers.XMLDOMWriterImpl.writeStartDocument(XMLDOMWriterImpl.java:583)
com.sun.xml.internal.stream.writers.XMLEventWriterImpl.add(XMLEventWriterImpl.java:96)
com.sun.xml.internal.stream.writers.XMLEventWriterImpl.add(XMLEventWriterImpl.java:72)
org.apache.jsp.gaga_jsp._jspService(gaga_jsp.java:95)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)使用XMLStreamReader和Writer编写文档
守则:
JSONObject obj = new JSONObject("{\"alice\": {\"bob\": \"a\"}}");
AbstractXMLStreamReader streamReader = new MappedXMLStreamReader(obj);
XMLInputFactory readerFactory = XMLInputFactory.newInstance();
XMLEventReader eventReader = readerFactory.createXMLEventReader(streamReader);
StringWriter stringWriter = new StringWriter();
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLEventWriter eventWriter = outputFactory.createXMLEventWriter(stringWriter);
eventWriter.add(eventReader);
eventWriter.close();
out.print(stringWriter.toString());使用Java 5,它查找找不到的com.bea.xml.stream.MXParserFactory:
javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found
javax.xml.stream.FactoryFinder.newInstance(FactoryFinder.java:72)
javax.xml.stream.FactoryFinder.find(FactoryFinder.java:178)
javax.xml.stream.FactoryFinder.find(FactoryFinder.java:92)
javax.xml.stream.XMLInputFactory.newInstance(XMLInputFactory.java:136)
org.apache.jsp.gaga_jsp._jspService(gaga_jsp.java:79)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)使用Java 6,它将导致Sun的XMLEventAllocatorImpl中的NPE
java.lang.NullPointerException
com.sun.xml.internal.stream.events.XMLEventAllocatorImpl.getXMLEvent(XMLEventAllocatorImpl.java:82)
com.sun.xml.internal.stream.events.XMLEventAllocatorImpl.allocate(XMLEventAllocatorImpl.java:55)
com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(XMLEventReaderImpl.java:86)
com.sun.xml.internal.stream.writers.XMLEventWriterImpl.add(XMLEventWriterImpl.java:72)
org.apache.jsp.gaga_jsp._jspService(gaga_jsp.java:85)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)使用BadgerFishDOMDocumentParser
代码:
ByteArrayInputStream bais = new ByteArrayInputStream("{\"alice\": {\"bob\": \"a\"}}".getBytes());
Document resDOM = new BadgerFishDOMDocumentParser().parse(bais);这一次给出了Sun's XMLEventAllocatorImpl中的NPE
java.lang.NullPointerException
com.sun.xml.internal.stream.events.XMLEventAllocatorImpl.getXMLEvent(XMLEventAllocatorImpl.java:82)
com.sun.xml.internal.stream.events.XMLEventAllocatorImpl.allocate(XMLEventAllocatorImpl.java:55)
com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(XMLEventReaderImpl.java:86)
com.sun.xml.internal.stream.writers.XMLEventWriterImpl.add(XMLEventWriterImpl.java:72)
org.codehaus.jettison.AbstractDOMDocumentParser.parse(AbstractDOMDocumentParser.java:66)
org.apache.jsp.gaga_jsp._jspService(gaga_jsp.java:79)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)发布于 2009-07-06 23:58:41
不,我不认为Xalan支持Stax,因为某种原因。撒克逊是这样做的,所以您可以尝试一下吗?
但是如果不是,也许您应该使用链接文本 (如这篇文章解释)从Stax构建一个DOM树?Xalan确实接受DOM源作为输入。
发布于 2009-05-12 20:26:04
JSON不是XML --看起来您试图使用XML解析器解析JSON对象吗?不过,我可能误解了你说的话。
发布于 2011-11-05 23:05:30
我也有这个问题,经历了和行动一样的挫折。有人提到这种行为是某个woodstox邮件列表中的一个bug。不过,我还是想出了解决办法。我编写了一个非常基本的XMLEventReader,它封装了一个XMLStreamReader,它做得很好。两个重要的注意事项: 1)这个代码是按原样提供的;具体来说,除了我自己有限的使用之外,我还没有对它进行彻底的测试;2)这个问题在互联网上几乎不存在,而且这似乎是一个相对基本的操作,抛弃应该执行,这强烈地告诉我,我们正在做一些根本错误的事情,这个解决方案不应该是必要的。用你自己的判断。
首先,下面是一个工作的XMLEventReader:
import java.util.LinkedList;
import java.util.Queue;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import com.sun.xml.internal.stream.events.AttributeImpl;
import com.sun.xml.internal.stream.events.CharacterEvent;
import com.sun.xml.internal.stream.events.CommentEvent;
import com.sun.xml.internal.stream.events.DTDEvent;
import com.sun.xml.internal.stream.events.EndDocumentEvent;
import com.sun.xml.internal.stream.events.EndElementEvent;
import com.sun.xml.internal.stream.events.NamespaceImpl;
import com.sun.xml.internal.stream.events.ProcessingInstructionEvent;
import com.sun.xml.internal.stream.events.StartDocumentEvent;
import com.sun.xml.internal.stream.events.StartElementEvent;
public class WorkingXMLEventReader implements XMLEventReader {
private final XMLStreamReader streamReader;
private final Queue<XMLEvent> eventQueue = new LinkedList<XMLEvent>();
public WorkingXMLEventReader (XMLStreamReader streamReader) {
this.streamReader = streamReader;
}
@Override public Object next () {
try {
return nextEvent();
} catch (XMLStreamException x) {
return null;
}
}
@Override public void remove () {
throw new UnsupportedOperationException("WorkingXMLEventReader iterator interface does not support remove()");
}
@Override public void close () throws XMLStreamException {
streamReader.close();
eventQueue.clear();
}
@Override public String getElementText () throws XMLStreamException {
return streamReader.getElementText();
}
@Override public Object getProperty (String key) throws IllegalArgumentException {
return streamReader.getProperty(key);
}
@Override public boolean hasNext () {
try {
return !eventQueue.isEmpty() || streamReader.hasNext();
} catch (XMLStreamException x) {
return false;
}
}
@Override public XMLEvent nextEvent () throws XMLStreamException {
if (eventQueue.isEmpty())
parseEvents(eventQueue, streamReader, streamReader.next());
return eventQueue.remove();
}
@Override public XMLEvent nextTag () throws XMLStreamException {
if (eventQueue.isEmpty())
parseEvents(eventQueue, streamReader, streamReader.nextTag());
return eventQueue.remove();
}
@Override public XMLEvent peek () throws XMLStreamException {
return eventQueue.peek();
}
protected static void parseEvents (Queue<XMLEvent> events, XMLStreamReader reader, int type) {
switch (type) {
case XMLEvent.START_ELEMENT:
events.add(new StartElementEvent(reader.getName()));
break;
case XMLEvent.END_ELEMENT:
events.add(new EndElementEvent(reader.getName()));
break;
case XMLEvent.CDATA:
events.add(new CharacterEvent(reader.getText(), true, false));
break;
case XMLEvent.SPACE:
events.add(new CharacterEvent(reader.getText(), false, true));
break;
case XMLEvent.CHARACTERS:
events.add(new CharacterEvent(reader.getText(), false, false));
break;
case XMLEvent.ATTRIBUTE:
for (int n = 0; n < reader.getAttributeCount(); ++ n) {
AttributeImpl attr = new AttributeImpl(reader.getAttributePrefix(n),
reader.getAttributeNamespace(n), reader.getAttributeLocalName(n),
reader.getAttributeValue(n), reader.getAttributeType(n));
events.add(attr);
}
break;
case XMLEvent.NAMESPACE:
for (int n = 0; n < reader.getNamespaceCount(); ++ n) {
NamespaceImpl ns = new NamespaceImpl(reader.getNamespacePrefix(n),
reader.getNamespaceURI(n));
events.add(ns);
}
break;
case XMLEvent.PROCESSING_INSTRUCTION:
events.add(new ProcessingInstructionEvent(reader.getPITarget(), reader.getPIData()));
break;
case XMLEvent.COMMENT:
events.add(new CommentEvent(reader.getText()));
break;
case XMLEvent.START_DOCUMENT:
events.add(new StartDocumentEvent(reader.getEncoding(), reader.getVersion()));
break;
case XMLEvent.END_DOCUMENT:
events.add(new EndDocumentEvent());
break;
case XMLEvent.DTD:
events.add(new DTDEvent(reader.getText()));
break;
}
}
}接下来,下面是如何在OP示例中使用它:
XMLStreamReader streamReader = new MappedXMLStreamReader(new JSONObject("{\"alice\":{\"bob\": \"a\"}}"));
XMLEventReader eventReader = new WorkingXMLEventReader(streamReader);
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
XMLEventWriter eventWriter = XMLOutputFactory.newInstance().createXMLEventWriter(new DOMResult(document));
eventWriter.add(eventReader);
eventWriter.close();
// test
Source testSource = new DOMSource(document);
Result testResult = new StreamResult(System.out);
TransformerFactory.newInstance().newTransformer().transform(testSource, testResult);输出应该类似于:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><alice><bob>a</bob></alice>希望这能帮到别人。
https://stackoverflow.com/questions/854344
复制相似问题