我正在尝试使用Stax编写XML数据,其中内容本身是HTML
如果我试试
xtw.writeStartElement("contents");
xtw.writeCharacters("<b>here</b>");
xtw.writeEndElement();
Run Code Online (Sandbox Code Playgroud)
我明白了
<contents><b>here</b></contents>
Run Code Online (Sandbox Code Playgroud)
然后我注意到CDATA方法并将我的代码更改为:
xtw.writeStartElement("contents");
xtw.writeCData("<b>here</b>");
xtw.writeEndElement();
Run Code Online (Sandbox Code Playgroud)
这次结果是
<contents><![CDATA[<b>here</b>]]></contents>
Run Code Online (Sandbox Code Playgroud)
这仍然不好.我真正想要的是
<contents><b>here</b></contents>
Run Code Online (Sandbox Code Playgroud)
那么是否有一个XML API /库允许我在不加入CDATA部分的情况下编写原始文本?到目前为止,我已经看过Stax和JDom了,他们似乎没有提供这个.
最后我可能会选择好的旧StringBuilder,但这不会很优雅.
更新:
到目前为止,我主要同意答案.但是,<b>here</b>我可以将1MB HTML文档嵌入到更大的XML文档中.你的建议意味着我必须解析这个HTML文档才能理解它的结构.如果可能的话,我想避免这种情况.
回答:
这是不可能的,否则您可能会创建无效的XML文档.
我浏览网页.我发现XMLStreamReader是用于解析XML的Cursor样式API.而XMLEventReader的是迭代器风格的API用于解析XML .Could任何一个详细的告诉我?
我试图通过Java NIO通道接收XML事件流.我是NIO和StAX解析的新手,所以我很容易忽略一些东西:)
我的搜索让我进入了几个SAX和StAX实现,但它们似乎都在InputStreams和InputSources上运行 - 而不是NIO通道.我最近的两次尝试是从通道获取InputStream并创建一个PipedInputStream:
// method 1
PipedOutputStream out = new PipedOutputStream();
InputStream in = new PipedInputStream(out);
PrintWriter writer = new PrintWriter(out);
//method 2
InputStream in = channel.socket().getInputStream()
//method 3
IputStream in = Channels.newInputStream(channel);
Run Code Online (Sandbox Code Playgroud)
其次是:
XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance()
.createXMLStreamReader(in);
//...
Run Code Online (Sandbox Code Playgroud)
当上面的代码与方法1一起使用时,它会在createXMLStreamReader行上阻塞.当使用方法2/3时,它们会立即抛出IllegalBlockingModeException(我明白为什么).也许需要一种新的方法?
我的目标是让一个非阻塞服务器select => accept来自客户端的字符数据=>使用特定的编码将其解析为XML事件=>将该事件对象转发到另一个线程进行处理=>并返回选择.
所以我忽略了一些东西,还是有更好的方法可以使用?如果是这样的话?
谢谢!
我正在寻找解决XSLT处理问题的方法.
是否可以使用并行处理来加速XSLT处理器?或者XSLT处理器本质上是串行的吗?
我的预感是XML可以被分割成可以由不同线程处理的块,但是由于我没有真正找到任何关于这种壮举的文档,我对此持怀疑态度.是否可以使用StAX同时分块XML?
似乎大多数XSLT处理器都是用Java或C/C++实现的,但我真的没有目标语言.我只想知道是否可以设想多线程XSLT处理器.
你的想法是什么?
我创建了一个XML模式(foo.xsd)并用于xjc为JAXB创建我的绑定类.假设根元素是collection,我正在写N个document对象,它们是复杂的类型.
因为我打算写出大型XML文件,我使用Stax写出collection根元素,而JAXB 使用编写文档子树Marshaller.marshal(JAXBElement, XMLEventWriter).这是jaxb非官方用户指南推荐的方法.
我的问题是,如何在编组时验证XML?如果我将模式绑定到JAXB marshaller(使用Marshaller.setSchema()),我会得到验证错误,因为我只是编组一个子树(它抱怨它没有看到collection根元素").我想我真正想做的是将模式绑定到的Stax XMLEventWriter或类似的东西.
对这种整体方法的任何评论都会有所帮助.基本上我希望能够使用JAXB来编组和解组大型XML文档而不会耗尽内存,所以如果有更好的方法可以让我知道.
使用XMLStreamReader开始学习StAX,我遇到了一些问题.如何将标签之间的所有内容作为文本?我的意思是,我知道所需标签的名称,当我找到它时,我必须转到关闭标签,我发现它们之间的所有内容我必须附加一些字符串.例如,我们有类似的东西
<rootTag>
...
<someTag>
Some text content and other tags here…
</someTag >
<tagINeed>
<someinternalTag1>
<someinternalTag11>
Some text content..
</someinternalTag11>
...
</someinternalTag1>
<someinternalTag2>
Something here
</someinternalTag2>
</tagINeed>
...
<somethingAnother>
...
</somethingAnother >
...
</rootTag>
Run Code Online (Sandbox Code Playgroud)
所以,我需要把我的字符串作为
<someinternalTag1>
<someinternalTag11>
Some text content..
</someinternalTag11>
...
</someinternalTag1>
<someinternalTag2>
Something here
</someinternalTag2>
Run Code Online (Sandbox Code Playgroud)
我怎么才能得到它?也许,我必须在源xml中找到所需块的开始和结束偏移,并在解析后给出子串?
我有一个巨大的XML(~2GB),我需要添加新元素并修改旧元素.例如,我有:
<books>
<book>....</book>
...
<book>....</book>
</books>
Run Code Online (Sandbox Code Playgroud)
并希望得到:
<books>
<book>
<index></index>
....
</book>
...
<book>
<index></index>
....
</book>
</books>
Run Code Online (Sandbox Code Playgroud)
我使用了以下代码:
XMLInputFactory inFactory = XMLInputFactory.newInstance();
XMLEventReader eventReader = inFactory.createXMLEventReader(new FileInputStream(file));
XMLOutputFactory factory = XMLOutputFactory.newInstance();
XMLStreamWriter writer = factory.createXMLStreamWriter(new FileWriter(file, true));
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.getEventType() == XMLEvent.START_ELEMENT) {
if (event.asStartElement().getName().toString().equalsIgnoreCase("book")) {
writer.writeStartElement("index");
writer.writeEndElement();
}
}
}
writer.close();
Run Code Online (Sandbox Code Playgroud)
但结果如下:
<books>
<book>....</book>
....
<book>....</book>
</books><index></index>
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
看来,这种方法的行为在Java 8中发生了变化.我需要一些快速解决我的问题.
问题是我有一些代码在每个命名的XML节点之后写入CR和LF <row>.现在(当我们迁移到Java 8时),而不是CR和LF,这些字符
被写出来.
同样,我需要一个快速修复,我不能改变StaX实现或做那样大的事情.
while (reader.hasNext()){
event = reader.next();
if (event == XMLStreamConstants.START_ELEMENT){
if (reader.getLocalName().equals("row")){
writer.writeCharacters("\r\n"); /// this is my problem now!!!
writer.writeStartElement(reader.getLocalName());
n = reader.getAttributeCount();
for (int i=0; i<n; i++){
name = reader.getAttributeName(i).getLocalPart();
value = reader.getAttributeValue(i);
...
}
}
Run Code Online (Sandbox Code Playgroud) 我javax.xml.stream.XMLStreamReader用来解析XML文档。不幸的是,我正在解析的某些文档使用非IANA编码名称,例如“ macroman”和“ ms-ansi”。例如:
<?xml version="1.0" encoding="macroman"?>
<foo />
Run Code Online (Sandbox Code Playgroud)
这将导致解析异常,并导致异常:
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,42]
Message: Invalid encoding name "macroman".
Run Code Online (Sandbox Code Playgroud)
有什么方法可以向我提供自定义编码处理程序,XMLStreamReader以便可以通过对所需编码的支持来增强它?
我正在使用 Java 11、Spring Boot 2.1.1 和 Apache CXF 3.2.7 来公开导入 XSD 架构的 SOAP Web 服务。在 WSDL 中,它显示如下:
<wsdl:import location="http://localhost:9000/endpoint/ws?wsdl=WS_endpointSoapPort.wsdl" namespace="http://test.com"> </wsdl:import>
Run Code Online (Sandbox Code Playgroud)
当我发送查询时,它失败并显示以下堆栈:
2018-12-31 12:05:54,908 ERROR se.[Tomcat].[localhost].[/].[CXFServlet]: 175 - Servlet.service() for servlet [CXFServlet] in context with path [] threw exception [Servlet execution threw an exception] with root cause
java.lang.NoSuchMethodError: org.codehaus.stax2.ri.EmptyIterator.getInstance()Lorg/codehaus/stax2/ri/EmptyIterator;
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?