gpt4 book ai didi

java - Sax:XMLReader:将 CSV 流式传输并转换为 Xml,同时验证结果

转载 作者:行者123 更新时间:2023-11-30 04:29:20 24 4
gpt4 key购买 nike

我必须将一些 CSV 文件(每个 > 600 MB)转换为 XML,同时使用 XSD 即时验证最终结果。

由于每个文件的大小,我使用 InputStreams 读取内容,并使用 OutpuStreams 将结果以 XML 形式流式传输回客户端。

让我们从简单的部分开始......(伪代码)

void transform(final InputStream CSVCustomerStream, final OutputStream outputStream) {
outputStream.write("<customers>")
foreach csvCustomerRow in CSVCustomerStream {
String xmlCustomerRow = csvCustomerRow.toXML();
outputStream.write(xmlCustomerRow.getBytes();
}
outputStream.write("</customers>")

**MISSING_XMLVALIDATOR.parse(outputStream);**
}

到目前为止,源 CSV 文件的每一行都已转换为 xml,然后写入输出流。

很简单。

但是,实际验证 xml 的部分仍然缺失。

为此我调查了XMLReader的 parse() 方法。唯一的问题是 parse() 只接受 InputSources,而同时我将要验证的内容流式传输到 OutputStream。

当然,在读取整个 CSV 内容后,我可以通过以下方式将 OutputStream 转换为 InputStream

 new ByteArrayInputStream((outputstream).toByteArray())

但这会立即将 600 MB 的 XML 重新带回内存,这违背了流式传输的全部目的。

PS:我无法控制 OutputStream 的确切实现,因为我的代码作为 REST-webservice 运行

    return Response.ok(new StreamingOutput() {
@Override
public void write(OutputStream output) throws Exception {
.... loading and transforming csv ...

}
}).build();

最佳答案

以您的 comment 为基础,让我提出“最糟糕”的可能场景,其中 XSD 被编写为俄罗斯娃娃(即,除了文档根之外,所有其他元素和类型都是在本地定义的)。由于这种风格,无法根据 XSD 验证 xmlCustomerRow,因为没有与您的标记相匹配的全局元素声明(假设 customer)。

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customers">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="customer" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>

</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

不过,解决方案并没有那么复杂。看看这个修改后的 XSD:

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customers">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="customer" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>

</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="customer">
<xsd:complexType>

</xsd:complexType>
</xsd:element>
</xsd:schema>

对于此设置,您只需以 XML 形式打开原始 XSD,克隆 customer 元素,删除其 minOccurs/maxOccurs 属性,然后将其作为 的子元素插入schema(它是 XML 中的文档元素)。这里的想法是,您可以即时或手动等进行重构。

总有可能您不必执行任何操作,即如果 customer 元素已经是全局的,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customers">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="customer" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="customer">
<xsd:complexType>

</xsd:complexType>
</xsd:element>
</xsd:schema>

可能会出现其他复杂情况,具体取决于您的 XSD 的实际外观,但我可以向您保证,其中没有任何内容可以阻止您进行任何可能需要的重构来实现您想要的目标。

我更认为,独立验证每条记录的能力胜过其他任何事情。更重要的是,对于在多核/CPU 计算机上运行的大量文件,您可以并行化验证,这将更有效地利用资源来实现更高的吞吐量。

关于java - Sax:XMLReader:将 CSV 流式传输并转换为 Xml,同时验证结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15034809/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com