【问题标题】:Filter out nodes from XML payload从 XML 有效负载中过滤掉节点
【发布时间】:2020-01-10 11:00:59
【问题描述】:

使用: Mule 3.9,Dataweave 1.0

我正在尝试通过子字段 (TestData.Orders.Items.ItemCategory) 的值过滤 XML 文档中不需要的节点。

在我的示例中,有 3 个项目,我需要删除 ItemCategory 字段中不包含值“CAT1”的项目。文档也是如此,但应该是相同的解决方案。

<TestData>
    <Orders uniqueId="6000:1234">
        <CoverPage>
            <Number>CPN-0001</Number>
        </CoverPage>
        <Items referentId="9000:100:10">
            <ItemNumber>AAA-0001</ItemNumber>
            <ItemCategory>CAT2|CAT3</ItemCategory>
            <Description>Just another description</ODescription>
        </Items>
        <Items referentId="9000:200:20">
            <ItemNumber>AAA-0002</ItemNumber>
            <ItemCategory>CAT2|CAT1|CAT3</ItemCategory>
            <OldItemDescription>Just another description</OldItemDescription>
        </Items>
        <Items referentId="9000:300:30">
            <ItemNumber>AAA-0003</ItemNumber>
            <ItemCategory>CAT2|CAT3</ItemCategory>
            <OldItemDescription>Just another description</OldItemDescription>
        </Items>
        <Page2/>
    </Orders>

    <Documents uniqueId="9000:100:10">
        <Title>
            <Number>AAA-0001</Number>
            <DocumentCategory>CAT2|CAT3</DocumentCategory>
        </Title>
        <ChangeHistory>
            <RelDate>2019-12-10T01:29:28Z</RelDate>
            <Number>CHN-0001</Number>
        </ChangeHistory>
    </Documents>
    <Documents uniqueId="9000:100:20">
        <Title>
            <Number>AAA-0002</Number>
            <DocumentCategory>CAT2|CAT1|CAT3</DocumentCategory>
        </Title>
        <ChangeHistory>
            <RelDate>2019-12-10T01:29:28Z</RelDate>
            <Number>CHN-0001</Number>
        </ChangeHistory>
    </Documents>
    <Documents uniqueId="9000:100:30">
        <Title>
            <Number>AAA-0003</Number>
            <DocumentCategory>CAT2|CAT3</DocumentCategory>
        </Title>
        <ChangeHistory>
            <RelDate>2019-12-10T01:29:28Z</RelDate>
            <Number>CHN-0001</Number>
        </ChangeHistory>
    </Documents>
</TestData>

所以我需要将上面的示例转换为下面的示例,只保留 ItemCategory 字段中包含值 'CAT1' 的 Items 和 Documents。

<TestData>
    <Orders uniqueId="6000:1234">
        <CoverPage>
            <Number>CPN-0001</Number>
        </CoverPage>
        <Items referentId="9000:200:20">
            <ItemNumber>AAA-0002</ItemNumber>
            <ItemCategory>CAT2|CAT1|CAT3</ItemCategory>
            <OldItemDescription>Just another description</OldItemDescription>
        </Items>
        <Page2/>
    </Orders>

    <Documents uniqueId="9000:100:20">
        <Title>
            <Number>AAA-0002</Number>
            <DocumentCategory>CAT2|CAT1|CAT3</DocumentCategory>
        </Title>
        <ChangeHistory>
            <RelDate>2019-12-10T01:29:28Z</RelDate>
            <Number>CHN-0001</Number>
        </ChangeHistory>
    </Documents>
</TestData>

过滤和重建策略:

我尝试了一种方法,我制作了 2 个过滤函数(一个用于项目,1 个用于文档),然后从头开始重建文档,

过滤器:

%function cleanItems(items) items filter ((lower $.ItemCategory contains 'cat1') == true)
%function cleanDocuments(docs) docs filter ((lower $.ns0#Title.DocumentCategory contains 'cat1') == true)

从头开始重建:

{
    TestData @(xmlns: "http://www.oracle.com/webfolder/technetwork/xml/plm/2014/08/"): {
        ChangeOrders @(uniqueId: payload.ns0#TestData.ns0#Orders.@uniqueId): {
        }
        ++ payload.ns0#TestData.*ns0#Orders.ns0#CoverPage
        ++ cleanItems(payload.ns0#TestData.*ns0#Orders.*ns0#Items)
        ++ payload.ns0#TestData.*ns0#Orders.ns0#PageTwo
    } 
    ++ cleanDocuments(payload.ns0#TestData.*ns0#Documents)
}

它基本上可以工作,但我失去了节点属性“xmlns”和“xmlns:xsd”以及“xmlns:xsi”和“xsi:schemaLocation”。

然后我尝试用这个 @(xmlns: "http://www.oracle.com/webfolder/technetwork/xml/plm/2014/08/") 输入缺少的属性 (https://docs.mulesoft.com/mule-runtime/4.2/dataweave-cookbook-insert-attribute) 但如果属性包含冒号 ':' 它会失败,我不知道如何逃离结肠。从头开始构建的另一个问题是我只能放入我知道的节点(文档没有 XSD)。

由于我尝试创建的功能是更大流程的一部分,因此我需要保持 XML 负载 100% 相同(但没有不需要的节点),否则会导致问题。

所以我正在考虑一种方法,可以从文档中删除不需要的节点,这样我就不必从头开始重建它。

希望你能帮忙,我能想到的都试过了。

【问题讨论】:

  • 我正在查看您的输入数据,并且正在与您提供的代码进行比较——我在输入数据中看不到命名空间。我怀疑您需要修改输入数据。

标签: xml mule dataweave


【解决方案1】:

试一试,如果命名空间是输入的一部分,它们应该保留在输出中。我可以让它更简单一点,但它已经晚了,我是脑死亡的 ATM。

%dw 1.0
%output application/xml

%var testKey = (k,v) ->     k as :string match {
    "Items"     -> ($ != "Items" or ($ == "Items" and (v.ItemCategory contains "CAT1"))),
    "Documents" -> ($ != "Documents" or ($ == "Documents" and (v.Title.DocumentCategory contains "CAT1"))) ,
    default     -> true
}

%var traverse = (ds) -> ds match {
    :object -> $ mapObject ( (v,k) -> (
        {((k): traverse(v)) when testKey(k,v)}
    ) ),
    default -> $
}
---
traverse(payload)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-19
    • 2019-11-06
    • 2018-04-19
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    相关资源
    最近更新 更多