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

如何在XSLT中选取packagingLevel为当前值减1的前置兄弟节点?

XSLT查找对应层级前置兄弟节点的TYPE_UE值问题

我是XSLT新手,做了相关研究后仍无法解决问题,特此求助。

我的XML结构中,每个units/results元素包含packagingLevel子节点。我需要找到当前节点的前置兄弟节点,其packagingLevel值等于当前节点的packagingLevel值减1,并获取该节点对应的转换后TYPE_UE值。例如当前节点packagingLevel为5时,找packagingLevel为4的兄弟节点对应的TYPE_UE。

输入XML示例

<root>
    <header>
        <products>
            <results>
                <units>
                    <results>
                        <itemCode>001</itemCode>
                        <packagingType>BOX</packagingType>
                        <eanCode>0000000000001</eanCode>
                        <packagingLevel>1</packagingLevel>
                        <quantity>1</quantity>
                    </results>
                    <results>
                        <itemCode>002</itemCode>
                        <packagingType>PALETTE</packagingType>
                        <eanCode>0000000000002</eanCode>
                        <packagingLevel>2</packagingLevel>
                        <quantity>1</quantity>
                    </results>
                </units>
            </results>
        </products>
    </header>
</root>

尝试的XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="/">
        <xsl:for-each select="//products/results">
            <Element>
                <xsl:for-each select="units/results">
                    <UE>
                        <UE_EAN>
                            <xsl:value-of select="eanCode" />
                        </UE_EAN>
                        <TYPE_UE>
                            <xsl:choose>
                                <xsl:when test="packagingLevel = 1">A01</xsl:when>
                                <xsl:when test="packagingType = 'BOX'">B01</xsl:when>
                                <xsl:when test="packagingType = 'PALETTE'">P01</xsl:when>
                            </xsl:choose>
                        </TYPE_UE>

                        <TYPE_UE_CONTENT>
                            <xsl:choose>
                                <xsl:when test="packagingLevel = 1">A01</xsl:when>
                                <xsl:otherwise>
                                    <xsl:variable name="prevLevel" select="preceding-sibling::units[packagingLevel = current()/packagingLevel - 1]/TYPE_UE" />
                                    <xsl:value-of select="$prevLevel"/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </TYPE_UE_CONTENT>

                        <UE_QTE>
                            <xsl:value-of select="quantite" />
                        </UE_QTE>
                    </UE>
                </xsl:for-each>
            </Element>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

当前输出

<Element>
    <... />
    <... />
    <UE>
        <UE_EAN>0000000000001</UE_EAN>
        <TYPE_UE>A01</TYPE_UE>
        <TYPE_UE_CONTENT>A01</TYPE_UE_CONTENT>
        <UE_QTY>1</UE_QTY>
    </UE>
    <UE>
        <UE_EAN>0000000000002</UE_EAN>
        <TYPE_UE>P01</TYPE_UE>
        <TYPE_UE_CONTENT />
        <UE_QTE>2</UE_QTE>
    </UE>
    <... />
</Element>

期望输出

<Element>
    <... />
    <... />
    <UE>
        <UE_EAN>0000000000001</UE_EAN>
        <TYPE_UE>A01</TYPE_UE>
        <TYPE_UE_CONTENT>A01</TYPE_UE_CONTENT>
        <UE_QTY>1</UE_QTY>
    </UE>
    <UE>
        <UE_EAN>0000000000002</UE_EAN>
        <TYPE_UE>P01</TYPE_UE>
        <TYPE_UE_CONTENT>A01</TYPE_UE_CONTENT>
        <UE_QTE>2</UE_QTE>
    </UE>
    <... />
</Element>

问题分析与修正方案

你的代码存在三个关键问题:

  1. 前置兄弟节点选择错误:当前节点是units/results,其兄弟节点是同层级的results,而非units,所以应该用preceding-sibling::results而非preceding-sibling::units。
  2. 无法直接引用转换后的TYPE_UE元素:TYPE_UE是你转换生成的节点,原XML中不存在,需要对找到的前置兄弟节点重新计算对应的TYPE_UE值。
  3. 拼写错误:原XML中是quantity,你代码里写的是quantite,导致UE_QTE值为空。

修正后的XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <!-- 定义复用的TYPE_UE计算模板,避免重复代码 -->
    <xsl:template name="get-type-ue">
        <xsl:param name="node"/>
        <xsl:choose>
            <xsl:when test="$node/packagingLevel = 1">A01</xsl:when>
            <xsl:when test="$node/packagingType = 'BOX'">B01</xsl:when>
            <xsl:when test="$node/packagingType = 'PALETTE'">P01</xsl:when>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="/">
        <xsl:for-each select="//products/results">
            <Element>
                <xsl:for-each select="units/results">
                    <UE>
                        <UE_EAN>
                            <xsl:value-of select="eanCode" />
                        </UE_EAN>
                        <TYPE_UE>
                            <xsl:call-template name="get-type-ue">
                                <xsl:with-param name="node" select="."/>
                            </xsl:call-template>
                        </TYPE_UE>

                        <TYPE_UE_CONTENT>
                            <xsl:choose>
                                <xsl:when test="packagingLevel = 1">A01</xsl:when>
                                <xsl:otherwise>
                                    <!-- 找到packagingLevel为当前层级-1的前置兄弟节点 -->
                                    <xsl:variable name="prev-sibling" select="preceding-sibling::results[packagingLevel = current()/packagingLevel - 1]"/>
                                    <!-- 调用模板计算对应的TYPE_UE值 -->
                                    <xsl:call-template name="get-type-ue">
                                        <xsl:with-param name="node" select="$prev-sibling"/>
                                    </xsl:call-template>
                                </xsl:otherwise>
                            </xsl:choose>
                        </TYPE_UE_CONTENT>

                        <UE_QTE>
                            <xsl:value-of select="quantity" />
                        </UE_QTE>
                    </UE>
                </xsl:for-each>
            </Element>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

修正说明

  • 新增get-type-ue模板,复用TYPE_UE的计算逻辑,避免重复代码,同时保证前置兄弟节点的TYPE_UE计算和当前节点一致。
  • 修正前置兄弟节点的选择表达式,正确定位到同层级的results节点。
  • 修复quantity的拼写错误,确保UE_QTE能正确取值。

运行修正后的代码即可得到你期望的输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:10:54