【问题标题】:Check XML Values from different Parents and replace value检查来自不同父母的 XML 值并替换值
【发布时间】:2018-08-18 17:09:20
【问题描述】:

我有一个情况,我需要一些点击来开发它:

XML 很大,我只包含一些部分:

<root>
    <header></header>
    <EventList>
        <ObjectEvent>
            <epcList />
            <biz>AAA</biz>
            <extension>
                <MATNR>1</MATNR>
                <PACK_LEVEL>1</PACK_LEVEL>
            </extension>
            <SAPExtension>
                <Attribute>
                    <LOTNO>1</LOTNO>
                </Attribute>
            </SAPExtension>
        </ObjectEvent>
        <ObjectEvent>
            <epcList>
                <epc>2</epc>
            </epcList>
            <biz>AAA</biz>
            <extension>
                <MATNR>1</MATNR>
                <PACK_LEVEL>1</PACK_LEVEL>
            </extension>
            <SAPExtension>
                <Attribute>
                    <LOTNO>1</LOTNO>
                </Attribute>
            </SAPExtension>
        </ObjectEvent>
        <ObjectEvent>
            <epcList>
                <epc>14</epc>
                <epc>11</epc>
                <epc>3</epc>
            </epcList>
            <biz>AAA</biz>
        </ObjectEvent>
        <ObjectEvent>
            <epcList>
                <epc>20</epc>
                <epc>555</epc>
                <epc>32</epc>
                <epc>1</epc>
                <epc>34</epc>
                <epc>34</epc>
                <epc>54</epc>
            </epcList>
            <biz>AAA</biz>
            <extension>
                <MATNR>1</MATNR>
                <PACK_LEVEL>1</PACK_LEVEL>
            </extension>
            <SAPExtension>
                <Attribute>
                    <LOTNO>1</LOTNO>
                </Attribute>
            </SAPExtension>
        </ObjectEvent>
        <AggregationEvent>
            <parentID>1</parentID>
            <readId/>
        </AggregationEvent>
        <AggregationEvent>
            <parentID>3</parentID>
            <readId/>
        </AggregationEvent>
        <AggregationEvent>
            <parentID>2</parentID>
            <readId/>
        </AggregationEvent>
        <AggregationEvent>
            <parentID>4</parentID>
            <readId/>
        </AggregationEvent>
    </EventList>
</root>

xml 包含所有时间 - 4+ = /ObjectEvent 和 4 /AggregationEvent

我需要获取Aggregation/parentID 的值并检查/ObjectEvent/epcList/Epc[1](仅限第一个位置,如果 xml 包含相同的值但与 epc 的第一个位置不同(忽略))如果等于 parentID价值。如果是并且 biz 等于 AAA,我需要将 /ObjectEvent/disposition 上的一个元素的值更改为布尔值 true

我已经开发了一个 xslt,请检查一下缺少什么?

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8"
        indent="yes" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="ObjectEvent/epcList">
        <xsl:variable name="EPC" select="../epcList/epc[1]" />
        <xsl:for-each select="//AggregationEvent">
            <xsl:variable name="parentID" select="./parentID" />
            <xsl:if test="$parentID=$EPC">
                <xsl:for-each select="//ObjectEvent">
                    <xsl:if
                        test="./epcList/epc=$parentID and ./bizStep=&apos;urn:epcglobal:cbv:bizstep:commissioning&apos;">
                        <xsl:element name="disposition">
                            <xsl:value-of select="'true'" />
                        </xsl:element>
                    </xsl:if>
                </xsl:for-each>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

XSLT 逻辑后的预期结果:(父 ID 包含在 epcList\epc 上(与位置无关)并且 biz 等于 AAA 从标签中选择值并添加到相对 parentID 的 AggregationEvent 上。

检查下面的预期结果:

ObjectEvent\epcList\epc 包含 (2)

<ObjectEvent>
    <epcList>
        <epc>20</epc>
        <epc>12</epc>
        <epc>2</epc>
        <epc>0</epc>
    </epcList>
    <biz>AAA</biz>
    <extension>
        <MATNR>1</MATNR>
        <PACK_LEVEL>1</PACK_LEVEL>
    </extension>
    <SAPExtension>
        <Attribute>
           <LOTNO>1</LOTNO>
        </Attribute>
    </SAPExtension>
</ObjectEvent>

parend id = 2 的聚合事件(在这种情况下):

<AggregationEvent>
    <parentID>1</parentID>
    <readId/>
</AggregationEvent>
<AggregationEvent>
    <parentID>3</parentID>
    <readId/>
</AggregationEvent>
<AggregationEvent>
    <parentID>2</parentID>
    <readId/>
    <extension>
                <MATNR>1</MATNR>
                <PACK_LEVEL>1</PACK_LEVEL>
            </extension>
            <SAPExtension>
                <Attribute>
                    <LOTNO>1</LOTNO>
                </Attribute>
            </SAPExtension>
</AggregationEvent>
<AggregationEvent>
    <parentID>4</parentID>
    <readId/>
</AggregationEvent>

但对 ObjectEvent 的这种处置但不在此位置:

enter image description here

谢谢

【问题讨论】:

  • 所以您想向满足条件的ObjectEvent 元素添加一个新的disposition 元素?或者您想在别处添加disposition?由于“结果”sn-p 以及您链接到的图像都包含输入样本中根本没有出现的各种元素,因此很难理解问题所在。
  • 您应该将样本减少到最少但完整且格式良好,以证明您需要帮助的问题,然后我们可以帮助解决该特定问题。然后,您应该可以将修复合并到更大的样式表中,或者使用更大、更复杂的 XML 输入。因此,请尝试通过发布最小但完整且格式良好的 XML 输入和 XSLT 以及您获得的输出以及您想要的输出来隔离当前问题,然后我们可以帮助解决该问题。
  • Martin,感谢支持,我已经修复了 xml 和需求,我在这里编码,现在只是缺少一点。

标签: xml xslt xslt-1.0


【解决方案1】:

由于extensionSAPExtension元素的值将被复制到匹配的Aggregation/parentID,只有ObjectEvent具有子元素biz = 'AAA'的值,模板需要更改如下

<xsl:template match="AggregationEvent">
    <xsl:copy>
        <xsl:apply-templates />
        <xsl:variable name="parentId" select="parentID" />
        <xsl:if test="../ObjectEvent[biz = 'AAA'][epcList/epc = $parentId]">
            <xsl:apply-templates select="../ObjectEvent[epcList/epc = $parentId]/extension" />
            <xsl:apply-templates select="../ObjectEvent[epcList/epc = $parentId]/SAPExtension" />
        </xsl:if>
    </xsl:copy>
</xsl:template>

完整的XSLT如下。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" />
    <xsl:strip-space elements="*" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="AggregationEvent">
        <xsl:copy>
            <xsl:apply-templates />
            <xsl:variable name="parentId" select="parentID" />
            <xsl:if test="../ObjectEvent[biz = 'AAA'][epcList/epc = $parentId]">
                <xsl:apply-templates select="../ObjectEvent[epcList/epc = $parentId]/extension" />
                <xsl:apply-templates select="../ObjectEvent[epcList/epc = $parentId]/SAPExtension" />
            </xsl:if>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

在共享输入 XML 中,epc12 都与对应的 parentID 匹配,因此节点被适当地复制。

请在https://xsltfiddle.liberty-development.net/6qVRKwu/1找到工作示例

【讨论】:

  • 感谢我测试的代码,但需求发生了变化 - ()
  • 使用聚合事件(Parent ID)并寻找一个 biz=AAA 事件,其 epcList/epc 包含 parentID 获取 parentID 的所有字段 ObjectEvent\Extension\ 和 ObjectEvent\SAPExtension\
  • 请更新示例输入 XML 和相应的输出,以使需求更清晰,便于理解。
  • Aniket,我只是用一个文件样本编辑您的回复以及必须做什么。感谢您的耐心和时间。
  • 我已经在问题中移动了更新的 XML 和预期的输出。展望未来,请使用更改更新问题,而不是在提供的解决方案中添加任何内容。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-16
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
相关资源
最近更新 更多