使用 XSL 连接几个 xml 符合特定条件的字段

Using XSL to concatenate several xml fields following certain criteria

我正在尝试使用 XSL 将几个 XML 字段连接到另一个 XML 字段中。

我想获取一个包含多个元素的 XML,我想根据某些条件将其中一些元素连接在一起,并将新连接的字符串添加到其中一个元素。

串联应遵循以下模式:

如果所有元素都在:build-Space-Item|Description

如果没有Space数据:build-Item|Description

如果没有项目:build-Space|Description

如果没有 Space 并且没有项目:build|Description

我是 XSLT 的新手,在尝试找到正确的语法来创建逻辑时遇到了麻烦。

我的 XML 看起来像这样:

<?xml version='1.0' encoding='UTF-8'?>
<document>
    <businessobjects>
        <BaseOrder>
            <Code>1190.00</Code>
            <Item>VE216</Item>
            <buil>CORP</buil>
            <Space></Space>
            <Type>Request</Type>
            <Description>Description 1</Description>
        </BaseOrder>
        <BaseOrder>
            <Code>64497.00</Code>
            <Item>HP01</Item>
            <buil>FO3</buil>
            <Space>002</Space>
            <Type>PPM</Type>
            <Description>Description 2</Description>
        </BaseOrder>
        <BaseOrder>
            <Code>77793.00</Code>
            <Item></Item>
            <buil>EN4</buil>
            <Space>123</Space>
            <Type>Request</Type>
            <Description>Description 3</Description>
        </BaseOrder>
        <BaseOrder>
            <Code>70796.00</Code>
            <Item></Item>
            <buil>SHS</buil>
            <Space></Space>
            <Type>Event</Type>
            <Description>Description 4</Description>
        </BaseOrder>
    </businessobjects>
</document>

我的输出 XML 应该像这样发送:

<?xml version='1.0' encoding='UTF-8'?>
<document>
    <businessobjects>
        <BaseOrder>
            <Code>1190.00</Code>
            <Description>CORP-VE216|Description 1</Description>
        </BaseOrder>
        <BaseOrder>
            <Code>64497.00</Code>
            <Description>FO3-002-HP01|Description 2</Description>
        </BaseOrder>
        <BaseOrder>
            <Code>77793.00</Code>
            <Description>EN4-123|Description 3</Description>
        </BaseOrder>
        <BaseOrder>
            <Code>70796.00</Code>
            <Description>SHS|Description 4</Description>
        </BaseOrder>
    </businessobjects>
</document>

我的 XSL 只捕捉到第一种情况,这可能是因为 choose(?)。谁能指导我如何正确执行此操作?

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="utf-8" media-type="xml/plain"/>
    <xsl:strip-space elements="*"/>

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

    <!-- drop elements with smart (kinda..) concat-->
<xsl:template match="BaseOrder">

    <BaseOrder>
        <xsl:variable name="noSpace" select="concat(build,'-',Item,'|')" />
        <xsl:variable name="noItem" select="concat(build,'-',Space,'|')" />
        <xsl:variable name="noSpaceItem" select="concat(build,'|')" />
        <xsl:variable name="full" select="concat(build,'-',Space,'-',Item,'|')" />
        
        <xsl:choose>
            <!-- no space -->
            <xsl:when test="not(@Space)">
                <Code>
                    <xsl:value-of select="Code"/>
                </Code>
                <Description>
                    <xsl:value-of select="concat($noSpace,Description)"/>
                </Description>
            </xsl:when>
            <!-- no Item -->
            <xsl:when test="not(@Item)">
                <Code>
                    <xsl:value-of select="Code"/>
                </Code>
                <Description>
                    <xsl:value-of select="concat($noItem,Description)"/>
                </Description>
            </xsl:when>
            <!-- no Space or Item -->
            <xsl:when test="not(@Space) and not(@Item)">
                <Code>
                    <xsl:value-of select="Code"/>
                </Code>
                <Description>
                    <xsl:value-of select="concat($noSpaceItem,Description)"/>
                </Description>
                
            </xsl:when>
            <!-- When all -->
            <xsl:otherwise>
                <Code>
                    <xsl:value-of select="Code"/>
                </Code>
                <Description>
                    <xsl:value-of select="concat($full,Description)"/>
                </Description>
                
            </xsl:otherwise>
        </xsl:choose>
    </BaseOrder>

</xsl:template>    

</xsl:stylesheet>

编辑:元素而非属性..

简单的怎么样:

XSLT 2.0

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

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

<xsl:template match="BaseOrder">
    <xsl:copy>
        <xsl:copy-of select="Code"/>
        <Description>
            <xsl:value-of select="buil, Space[text()], Item[text()]" separator="-"/>
            <xsl:text>|</xsl:text>
            <xsl:value-of select="Description"/>
         </Description>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

或者,如果您愿意:

<xsl:template match="BaseOrder">
    <xsl:copy>
        <xsl:copy-of select="Code"/>
        <Description>
            <xsl:value-of select="string-join((buil, Space/text(), Item/text()), '-'), Description" separator="|"/>
         </Description>
    </xsl:copy>
</xsl:template>