Camel,使用字段条件拆分带头的大型XML文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Camel,使用字段条件拆分带头的大型XML文件相关的知识,希望对你有一定的参考价值。

我正在尝试设置一个Apache Camel路由,它输入一个大的XML文件,然后使用字段条件将有效负载分成两个不同的文件。即如果ID字段以1开头,则转到一个输出文件,否则转到另一个。使用Camel不是必须的,我也看过XSLT和常规Java选项,但我觉得这应该可行。

我已经介绍了拆分实际的有效负载,但我遇到了确保父节点(包括标头)也包含在每个文件中的问题。由于文件可能很大,我想确保将流用于有效负载。我觉得我在这里已经阅读了数百个不同的问题,博客条目等等,几乎每个案例都包括将整个文件加载到内存中,将文件平均分成几部分,只需单独使用有效负载节点。

我的原型XML文件如下所示:

<root>
    <header>
        <title>Testing</title>
    </header>
    <orders>
        <order>
            <id>11</id>
            <stuff>One</stuff>
        </order>
        <order>
            <id>20</id>
            <stuff>Two</stuff>
        </order>
        <order>
            <id>12</id>
            <stuff>Three</stuff>
        </order>
    </orders> 
</root>

结果应该是两个文件 - 条件为true(id以1开头):

<root>
    <header>
        <title>Testing</title>
    </header>
    <orders>
        <order>
            <id>11</id>
            <stuff>One</stuff>
        </order>
        <order>
            <id>12</id>
            <stuff>Three</stuff>
        </order>
    </orders> 
</root>

条件错误:

<root>
    <header>
        <title>Testing</title>
    </header>
    <orders>
        <order>
            <id>20</id>
            <stuff>Two</stuff>
        </order>
    </orders> 
</root>

我的原型路线:

from("file:" + inputFolder)
.log("Processing file ${headers.CamelFileName}")
.split()
    .tokenizeXML("order", "*") // Includes parent in every node
    .streaming()
    .choice()
        .when(body().contains("id>1"))
            .to("direct:ones")
            .stop()
        .otherwise()
            .to("direct:others")
            .stop()
    .end()
.end();

from("direct:ones")
//.aggregate(header("ones"), new StringAggregator()) // missing end condition
.to("file:" + outputFolder + "?fileName=ones-${in.header.CamelFileName}&fileExist=Append");

from("direct:others")
//.aggregate(header("others"), new StringAggregator()) // missing end condition
.to("file:" + outputFolder + "?fileName=others-${in.header.CamelFileName}&fileExist=Append");

除了为每个节点添加父标记(页眉和页脚,如果你愿意)之外,它的工作方式也是如此。仅使用tokenizeXML中的节点仅返回节点本身,但我无法弄清楚如何添加页眉和页脚。我希望将父标签流式传输到页眉和页脚属性,并在拆分之前和之后添加它们。

我怎样才能做到这一点?我是否需要首先对父标签进行标记,这是否意味着将文件流式传输两次?

最后一点,您可能会注意到最后的汇总。我不想在写入文件之前聚合每个节点,因为这会破坏流式传输的目的并使整个文件保持内存不足,但我想我可能会在写入之前聚合多个节点来获得一些性能。文件,以减少为每个节点写入驱动器的性能。我不确定这是否有意义。

以上是关于Camel,使用字段条件拆分带头的大型XML文件的主要内容,如果未能解决你的问题,请参考以下文章

我以什么格式为camel-sap提供BCD字段?

使用 Camel 并行处理大型 SQL 表

Camel Rest XML DSL分离文件夹结果Unmarshall Exception

解析大型 XML 文件?

Camel JDBC StreamList 查询似乎在拆分之前加载了整个结果集

如何使用 xsl 拆分 html 文件?