You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过动态属性值匹配将Article节点迁移至对应OrderLine节点

XML节点迁移通用XSLT实现

需求说明

需要将XML中的Article节点迁移至对应的OrderLine节点,匹配规则为Article的UserArea中DropPoint属性值与OrderLine的LineNumber值一致,无论Article原本归属哪个OrderLine。现有XSLT代码通过固定LineNumber值(如10、20、30)可实现该功能,但因无法预先知晓OrderLine的数量及编号,需修改为无需固定值的通用实现。

源XML示例

<SyncOrder>
<DataArea>
    <Order>
        <OrderHeader>
        </OrderHeader>
        <OrderLine>
            <LineNumber>10</LineNumber>
            <Article>
                <LineNumber>10</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">30</NameValue>
                    </Property>
                </UserArea>
            </Article>
        </OrderLine>
        <OrderLine>
            <LineNumber>20</LineNumber>
            <Article>
                <LineNumber>20</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">10</NameValue>
                    </Property>
                </UserArea>
            </Article>
            <Article>
                <LineNumber>30</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">10</NameValue>
                    </Property>
                </UserArea>
            </Article>
            <Article>
                <LineNumber>50</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">10</NameValue>
                    </Property>
                </UserArea>
            </Article>
        </OrderLine>
        <OrderLine>
            <LineNumber>30</LineNumber>
            <Article>
                <LineNumber>40</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">10</NameValue>
                    </Property>
                </UserArea>
            </Article>
        </OrderLine>
    </Order>
</DataArea>
</SyncOrder>

目标XML示例

<SyncOrder>
<DataArea>
    <Order>
        <OrderHeader>
        </OrderHeader>
        <OrderLine>
            <LineNumber>10</LineNumber>
            <Article>
                <LineNumber>20</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">10</NameValue>
                    </Property>
                </UserArea>
            </Article>
            <Article>
                <LineNumber>30</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">10</NameValue>
                    </Property>
                </UserArea>
            </Article>
            <Article>
                <LineNumber>40</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">10</NameValue>
                    </Property>
                </UserArea>
            </Article>
            <Article>
                <LineNumber>50</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">10</NameValue>
                    </Property>
                </UserArea>
            </Article>
        </OrderLine>
        <OrderLine>
            <LineNumber>20</LineNumber>
        </OrderLine>
        <OrderLine>
            <LineNumber>30</LineNumber>
            <Article>
                <LineNumber>10</LineNumber>
                <UserArea>
                    <Property>
                        <NameValue
                            name="DropPoint"
                            type="StringType">30</NameValue>
                    </Property>
                </UserArea>
            </Article>
        </OrderLine>
    </Order>
</DataArea>
</SyncOrder>

现有固定值实现代码

<xsl:template match="@* | node()">
<xsl:copy>
 <xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="//dns:Order/*:OrderLine/*:Article">
<xsl:element name="{name(.)}" />
</xsl:template>

<xsl:template match="//dns:Order/*:OrderLine">
 <xsl:if test="./*:LineNumber/text() = '10'">
   <xsl:copy>
    <xsl:apply-templates select="node() | @* " />
     <xsl:for-each select="/*:SyncOrder/*:DataArea/*:Order/*:OrderLine/*:Article">
      <xsl:if test="./*:UserArea/*:Property/*:NameValue[@name='DropPoint']/text() ='10'">
       <xsl:copy>
        <xsl:apply-templates select="node() | @* " />
       </xsl:copy>
      </xsl:if>
     </xsl:for-each>
    </xsl:copy>
  </xsl:if>
 <xsl:if test="./*:LineNumber/text() = '20'">
   <xsl:copy>
    <xsl:apply-templates select="node() | @* " />
     <xsl:for-each select="/*:SyncOrder/*:DataArea/*:Order/*:OrderLine/*:Article">
      <xsl:if test="./*:UserArea/*:Property/*:NameValue[@name='DropPoint']/text() ='20'">
       <xsl:copy>
        <xsl:apply-templates select="node() | @* " />
       </xsl:copy>
      </xsl:if>
     </xsl:for-each>
    </xsl:copy>
  </xsl:if>
 <xsl:if test="./*:LineNumber/text() = '30'">
   <xsl:copy>
    <xsl:apply-templates select="node() | @* " />
     <xsl:for-each select="/*:SyncOrder/*:DataArea/*:Order/*:OrderLine/*:Article">
      <xsl:if test="./*:UserArea/*:Property/*:NameValue[@name='DropPoint']/text() ='30'">
       <xsl:copy>
        <xsl:apply-templates select="node() | @* " />
       </xsl:copy>
      </xsl:if>
     </xsl:for-each>
    </xsl:copy>
  </xsl:if>
</xsl:template>

通用版XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 身份模板:复制所有节点和属性,默认规则 -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 屏蔽原OrderLine下的Article节点,不输出原节点 -->
    <xsl:template match="OrderLine/Article"/>

    <!-- 处理OrderLine节点,添加匹配的Article -->
    <xsl:template match="OrderLine">
        <xsl:copy>
            <!-- 复制当前OrderLine的原有节点(除了Article) -->
            <xsl:apply-templates select="@* | node()[not(self::Article)]"/>
            <!-- 筛选所有Article中DropPoint值等于当前OrderLine的LineNumber的节点 -->
            <xsl:variable name="currentLineNum" select="LineNumber/text()"/>
            <xsl:for-each select="/SyncOrder/DataArea/Order/OrderLine/Article">
                <xsl:if test="UserArea/Property/NameValue[@name='DropPoint']/text() = $currentLineNum">
                    <xsl:copy>
                        <xsl:apply-templates select="@* | node()"/>
                    </xsl:copy>
                </xsl:if>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

代码说明

  1. 身份模板:保留XML的基本结构,复制所有未被特殊模板匹配的节点和属性。
  2. 屏蔽原Article节点:通过匹配OrderLine/Article并不做任何输出,移除原来归属在各个OrderLine下的Article。
  3. 通用OrderLine处理:
    • 复制当前OrderLine的所有原有内容(排除Article)
    • 定义变量currentLineNum获取当前OrderLine的LineNumber值
    • 遍历所有Article节点,筛选出DropPoint值与currentLineNum一致的节点,复制到当前OrderLine下

内容的提问来源于stack exchange,提问作者skater123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:21:59