stax 相关问题

StAX代表Streaming API for XML。它是一个基于Java的流式,事件驱动的拉解析API,用于读取和编写XML文档。

使用 Stax2 转义 Scala 中的特殊字符

我正在尝试使用 Stax2 来编写带有转义特殊字符的属性的 xml 文件。 当我试图实现这样的精确输出时: 我正在尝试使用 Stax2 来编写带有转义特殊字符的属性的 xml 文件。 当我试图实现这样的精确输出时: <elem1 att1="This &#x0A; That" /> 但是当我使用通常的XMLStreamWriter时,输出是这样的: <elem1 att1="This &amp;#x0A; That" /> 所以我用 Stax2 尝试了以下操作: import org.codehaus.stax2.{XMLOutputFactory2} import org.scalatest.funsuite.AnyFunSuite import java.io.{File, FileOutputStream} import javax.xml.stream.{XMLOutputFactory, XMLStreamWriter} class testStreamXML extends AnyFunSuite{ val file = new File("stax2test.xml") val fileOutputStream = new FileOutputStream(file) val outputFactory: XMLOutputFactory2 = XMLOutputFactory.newInstance().asInstanceOf[XMLOutputFactory2] //outputFactory.setProperty(XMLOutputFactory2.P_ATTR_VALUE_ESCAPER, true) val writer= outputFactory.createXMLStreamWriter(fileOutputStream) writer.writeStartDocument() writer.writeStartElement("elem1") writer.writeAttribute("att1", "This &#x0A; That") writer.writeEndElement() writer.writeEndDocument() } 每当我尝试将属性 P_ATTR_VALUE_ESCAPER 设置为 true 或 false 时,我都会收到此错误: An exception or error caused a run to abort: class java.lang.Boolean cannot be cast to class org.codehaus.stax2.io.EscapingWriterFactory (java.lang.Boolean is in module java.base of loader 'bootstrap'; org.codehaus.stax2.io.EscapingWriterFactory is in unnamed module of loader 'app') java.lang.ClassCastException: class java.lang.Boolean cannot be cast to class org.codehaus.stax2.io.EscapingWriterFactory (java.lang.Boolean is in module java.base of loader 'bootstrap'; org.codehaus.stax2.io.EscapingWriterFactory is in unnamed module of loader 'app') at com.ctc.wstx.api.WriterConfig.setProperty(WriterConfig.java:401) at com.ctc.wstx.api.CommonConfig.setProperty(CommonConfig.java:100) at com.ctc.wstx.stax.WstxOutputFactory.setProperty(WstxOutputFactory.java:153) at testStreamXML3.<init>(testStreamXML3.scala:10) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128) at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:350) at java.base/java.lang.Class.newInstance(Class.java:645) at org.scalatest.tools.Runner$.genSuiteConfig(Runner.scala:1402) at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$8(Runner.scala:1199) at scala.collection.immutable.List.map(List.scala:246) at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1198) at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24(Runner.scala:993) at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24$adapted(Runner.scala:971) at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1480) at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:971) at org.scalatest.tools.Runner$.run(Runner.scala:798) at org.scalatest.tools.Runner.run(Runner.scala) at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2or3(ScalaTestRunner.java:38) at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:25) 有什么建议如何解决这个问题吗?或者达到我转义属性中特殊字符的目的? 您所指的属性确实需要一个 EscapingWriterFactory 类。这是文档: 如果需要对属性值内容进行自定义输出转义,可以设置的属性。值集必须是类型 逃离WriterFactory。设置后,工厂将用于创建 每个写入器实例用于转义所有写入的属性值,两者 通过显式 XMLStreamWriter.writeAttribute(java.lang.String, java.lang.String) 方法,以及通过复制方法 (XMLStreamWriter2.copyEventFromReader(org.codehaus.stax2.XMLStreamReader2, 布尔值))。 [1] 关于如何实现“个人”逃避该工厂的实施的问题就可以完成这项工作。这是一个使用给定编写器的简单实现(受 [2] 启发),无需应用任何转义 - 这可能是您想要解决的任何特殊用例的起点: class CustomXmlEscapingWriterFactory extends EscapingWriterFactory{ override def createEscapingWriterFor(writer: Writer, s: String): Writer = new Writer(){ override def write(cbuf: Array[Char], off: Int, len: Int): Unit = writer.write(cbuf, off, len) override def flush(): Unit = writer.flush() override def close(): Unit = writer.close() } override def createEscapingWriterFor(outputStream: OutputStream, s: String): Writer = throw IllegalArgumentException("not supported") } class TestStreamXML extends AnyFunSuite{ val file = new File("stax2test.xml") val fileOutputStream = new FileOutputStream(file) val oprovider: OutputFactoryProviderImpl = new OutputFactoryProviderImpl() val outputFactory: XMLOutputFactory2 = oprovider.createOutputFactory() // your factory implementation goes here as property outputFactory.setProperty(XMLOutputFactory2.P_ATTR_VALUE_ESCAPER, CustomXmlEscapingWriterFactory()) val writer= outputFactory.createXMLStreamWriter(fileOutputStream) writer.writeStartDocument() writer.writeStartElement("elem1") writer.writeAttribute("att1", "This &#x0A; That") writer.writeEndElement() writer.writeEndDocument() } 结果输出如下所示: <?xml version='1.0' encoding='UTF-8'?><elem1 att1="This &#x0A; That"/> [1] https://fasterxml.github.io/stax2-api/javadoc/4.0.0/org/codehaus/stax2/XMLOutputFactory2.html#P_ATTR_VALUE_ESCAPER [2] 使用 jackson-dataformat-xml 转义引号

回答 1 投票 0

STAX 解析器因大型 XML 而失败

我遇到了一个很奇怪的情况。 我有 2 个 XML,我正在尝试将它们合并并形成一个 XML。 我正在使用 STAX Parser 来实现它。 它与小文件完美配合,但...

回答 2 投票 0

XMLStreamReader.getLocation() 返回意外的字符偏移量

给出以下代码: 导入 javax.xml.stream.XMLInputFactory; 导入 java.io.ByteArrayInputStream; 导入 java.nio.charset.StandardCharsets; 类划痕{ 公共静态无效主(字符串[]

回答 1 投票 0

了解 XMLStreamReader 和 START_DOCUMENT

考虑以下 XML 文件: % cat 测试.xml 为什么我在使用

回答 1 投票 0

了解 XMLStreamReader 和 START_ELEMENT

考虑以下 XML 文件: % cat 测试.xml 为什么我在使用

回答 1 投票 0

使用StAX从父元素解析文本和元素

DL/DR; 我正在使用 StAX 流式解析 XML 文件以提取一些数据。 我遇到的问题是,当我遇到一个包含文本和另一个元素的元素时,当我尝试提取...

回答 1 投票 0

使用 woodstox 和本地 dtd 验证和解析 xml

我看到了多个与使用 woodstox 和 JAXB 解析 xml 相关的问题,以使用 XMLStreamReader 解组并根据模式进行验证。尽管阅读它们并没有帮助。我需要什么...

回答 1 投票 0

带有 XMLEventWriter 的自关闭标签

所以问题就如标题所述。我正在做一些 xml 工作并使用 XMLEventWriter。我遇到的大问题是我需要创建一些自关闭标签 问题...

回答 2 投票 0

StaX解析:Transformer.transform方法自动移动光标,并不总是很好

我正在使用 XMLStreamReader 来实现我的目标(分割 xml 文件)。看起来不错,但仍然没有给出想要的结果。我的目标是从输入文件中分割每个节点“nextTag”: 我正在使用 XMLStreamReader 来实现我的目标(分割 xml 文件)。看起来不错,但仍然没有给出想要的结果。我的目标是从输入文件中分割每个节点“nextTag”: <?xml version="1.0" encoding="UTF-8"?> <firstTag> <nextTag>1</nextTag> <nextTag>2</nextTag> </firstTag> 结果应该是这样的: <?xml version="1.0" encoding="UTF-8"?><nextTag>1</nextTag> <?xml version="1.0" encoding="UTF-8"?><nextTag>2</nextTag> 参考使用Java分割1GB Xml文件我用这段代码实现了我的目标: import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stax.StAXSource; import javax.xml.transform.stream.StreamResult; public class Demo4 { public static void main(String[] args) throws Exception { InputStream inputStream = new FileInputStream("input.xml"); BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); XMLInputFactory factory = XMLInputFactory.newInstance(); TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); XMLStreamReader streamReader = factory.createXMLStreamReader(in); while (streamReader.hasNext()) { streamReader.next(); if (streamReader.getEventType() == XMLStreamReader.START_ELEMENT && "nextTag".equals(streamReader.getLocalName())) { StringWriter writer = new StringWriter(); t.transform(new StAXSource(streamReader), new StreamResult( writer)); String output = writer.toString(); System.out.println(output); } } } } 其实很简单。但是,我的输入文件是单行形式: <?xml version="1.0" encoding="UTF-8"?><firstTag><nextTag>1</nextTag><nextTag>2</nextTag></firstTag> 我的 Java 代码不再产生所需的输出,而只是这个结果: <?xml version="1.0" encoding="UTF-8"?><nextTag>1</nextTag> 花了几个小时后,我很确定已经找出原因了: t.transform(new StAXSource(streamReader), new StreamResult(writer)); 这是因为,执行完transform方法后,光标会自动前进到下一个事件。在代码中,我有这个分数: while (streamReader.hasNext()) { streamReader.next(); ... t.transform(new StAXSource(streamReader), new StreamResult(writer)); ... } 第一次变换后,streamReader直接获取2次next(): 1. from the transform method 2. from the next method in the while loop 因此,对于此特定行 XML,光标永远无法到达第二个打开标记。 相反,如果输入 XML 具有漂亮的打印形式,则可以从光标到达第二个,因为第一个结束标记后面有一个空格事件 不幸的是,我找不到任何如何进行设置的内容,因此变换器在执行变换方法后不会自动跳到下一个事件。这太令人沮丧了。 有人知道我该如何处理吗?在语义上也很受欢迎。非常感谢。 问候, 拉特纳 PS。我肯定可以为这个问题写一个解决方法(在转换之前漂亮地打印 xml 文档,但这意味着输入 xml 之前已被修改,这是不允许的) 正如您所阐述的,如果元素节点直接相互跟随,转换步骤是否会继续到下一个创建元素。 为了解决这个问题,您可以使用嵌套 while 循环重写代码,如下所示: while(reader.next() != XMLStreamConstants.END_DOCUMENT) { while(reader.getEventType() == XMLStreamConstants.START_ELEMENT && reader.getLocalName().equals("nextTag")) { StringWriter writer = new StringWriter(); // will transform the current node to a String, moves the cursor to the next START_ELEMENT t.transform(new StAXSource(reader), new StreamResult(writer)); System.out.println(writer.toString()); } } 如果您的 xml 文件适合内存,您可以在 JOOX 库的帮助下尝试,该库在 gradle 中导入,例如: compile 'org.jooq:joox:1.3.0' 还有主类,比如: import java.io.File; import java.io.IOException; import org.joox.JOOX; import org.joox.Match; import org.w3c.dom.Document; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import static org.joox.JOOX.$; public class Main { public static void main(String[] args) throws IOException, SAXException, TransformerException { DocumentBuilder builder = JOOX.builder(); Document document = builder.parse(new File(args[0])); Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty("omit-xml-declaration", "no"); final Match $m = $(document); $m.find("nextTag").forEach(tag -> { try { transformer.transform( new DOMSource(tag), new StreamResult(System.out)); System.out.println(); } catch (TransformerException e) { System.exit(1); } }); } } 它产生: <?xml version="1.0" encoding="UTF-8"?><nextTag>1</nextTag> <?xml version="1.0" encoding="UTF-8"?><nextTag>2</nextTag>

回答 2 投票 0

如何将未转义的 XML 写入 XMLStreamWriter?

我有许多小的 XML 块,它们应该作为子元素嵌入到一个大的 XML 中。有什么方法可以将这些块写入 XMLStreamWriter 而不转义它们吗?

回答 4 投票 0

Apache POI 在 Android 上如何满足依赖?

Android上有很多关于用Apache POI阅读.docx文件的帖子。我编写 Java 程序,它执行并希望将它移动到 Android 平台。但是 XWPFDocument 需要 xmlbeans.jar 和 xmlbeans....

回答 2 投票 0

当节点并列时,Stax 变换似乎不起作用

我想使用基于拆分基础节点的 StAX 技术将一个大的 XML 文件拆分成许多部分。 问题是当拆分基础节点并列时(没有空格,没有制表符,也没有断线下注......

回答 0 投票 0

使用StAX写入现有xml文件

我正在使用StAX将新的Record对象添加到名为“ archive.xml”的XML文件中。通用方法是:检查文件是否存在-如果不存在-创建一个新文件;创建XMLEventReader和XMLEventWriter; 3.1如果文件...

回答 1 投票 0

Java stax:3字节UTF-8序列的无效字节2

[我正在尝试使用stax解析xml,但我得到的错误是:javax.xml.stream.XMLStreamException:[row,col]:[8,64]处的ParseError消息:3字节UTF-的无效字节2 8序列。我已经...

回答 1 投票 0

使用STAX检索字符串值

我在下面有以下代码,在这种情况下,我想做的就是检索特定元素的值SettDate。我尝试了许多不同的方法,但是我一直得到null ...

回答 1 投票 0

Java:如何使用stax从xml获取特定信息

我无法使用stax从我的xml获取特定信息。在我的xml内,我有一个当前值和平均值,这两个值中都有一个旅行时间。但是我只想获取旅行时间...

回答 1 投票 0

关于在无休止的xml文件流中使用StAX的问题

我有一台正在运行的服务器,每秒发送一个xml文件(最终需要将其升级到每秒800个文件)。我写的监听服务器的客户端,处理第一个文件...

回答 1 投票 2

“无法为传递的源创建Stax阅读器”错误

我有以下代码:public Object unmarshal(源代码,MimeContainer mimeContainer)抛出XmlMappingException {AttachmentUnmarshaller au = null;如果(this.mtomEnabled && ...

回答 1 投票 0

XMLEventReader和XMLEventWriter在同一文件上?

由于我不了解文件系统的行为,所以我事先表示歉意。我需要读取一个大型XML文件,对其进行修改,然后将其写到同一文件中。这是我的代码,用于设置XMLEventReader ...

回答 1 投票 0

[在Spring Boot Java中从数据库生成xml

我想通过jpa查询到xml从表中生成/编组Java对象的流/集合。我正在处理这些Java对象,并将它们批量转换为xml。我想...

回答 1 投票 1

© www.soinside.com 2019 - 2024. All rights reserved.