Xslt 使用xpath访问分组节点以构建常量输出

Xslt 使用xpath访问分组节点以构建常量输出,xslt,key,xslt-2.0,xslt-grouping,Xslt,Key,Xslt 2.0,Xslt Grouping,我有下面的xml <toPay> <Pay> <amount>1111</amount> <accountNumber>223128987</accountNumber> <payType>PAYROLL</payType> </Pay> <Pay> <amount>2222</amount> <

我有下面的xml

<toPay>
<Pay>
    <amount>1111</amount>       
    <accountNumber>223128987</accountNumber>
    <payType>PAYROLL</payType>
</Pay>
<Pay>
    <amount>2222</amount>
    <accountNumber>123128987</accountNumber>
    <payType>PAYROLL</payType>
</Pay>
<Pay>
    <amount>333</amount>
    <accountNumber>645032</accountNumber>
    <payType>MAIN</payType>
</Pay>

1111
223128987
工资名单
2222
123128987
工资名单
333
645032
主要

我需要以下格式的输出:

<root>
<element>
    <amount>1111</amount>
    <accountNumber>223128987</accountNumber>
</element>
<element>
    <amount>2222</amount>
    <accountNumber>223128987</accountNumber>
</element>
<element>
    <amount></amount>
    <accountNumber></accountNumber>
</element>
<element>
    <amount></amount>
    <accountNumber></accountNumber>
</element>

1111
223128987
2222
223128987

我编写了以下代码:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="groups" match="payType" use="." />

<xsl:template match="/toPay/Pay">
    <root>
        <xsl:apply-templates select="payType[generate-id() = generate-id(key('groups', .)[1])]" />
    </root>
</xsl:template>

<xsl:template match="payType">
    <xsl:variable name="currentGroup" select="." />
        <xsl:if test="$currentGroup = 'PAYROLL'">

            <xsl:for-each select="key('groups', $currentGroup)">
                <element>
                    <xsl:if test="position() = 1">
                        <amount>
                            <xsl:value-of select="../amount" />
                        </amount>
                        <accountNumber>
                            <xsl:value-of select="../accountNumber" />
                        </accountNumber>
                    </xsl:if>                   
                    <xsl:if test="position() = 2">
                        <amount>
                            <xsl:value-of select="../amount" />
                        </amount>
                        <accountNumber>
                            <xsl:value-of select="../accountNumber" />
                        </accountNumber>
                    </xsl:if>
                </element>
            </xsl:for-each>
        </xsl:if>
</xsl:template>

但我面临的问题是——我无法访问paytype的分组节点——PAYROLL。我知道的唯一方法是position,但我要求始终在输出中输入4个元素节点,无论PAYtype-PAYROLL的源xml中的节点是否存在。 如果存在,则填充相同EED的值;如果不存在,则填充没有值的xml标记


非常感谢任何帮助—xslt 1.0或2.0。

如果我正确理解了您的解释,您可以做一些非常简单的事情—即使有点原始:

<xsl:template match="/toPay">
    <xsl:variable name="payroll" select="Pay[payType='PAYROLL']" />
    <root>
        <element>
            <amount>
                <xsl:value-of select="$payroll[1]/amount" />
            </amount>
            <accountNumber>
                <xsl:value-of select="$payroll[1]/accountNumber" />         
            </accountNumber>
        </element>
        <element>
            <amount>
                <xsl:value-of select="$payroll[2]/amount" />
            </amount>
            <accountNumber>
                <xsl:value-of select="$payroll[2]/accountNumber" />         
            </accountNumber>
        </element>
        <element>
            <amount>
                <xsl:value-of select="$payroll[3]/amount" />
            </amount>
            <accountNumber>
                <xsl:value-of select="$payroll[3]/accountNumber" />         
            </accountNumber>
        </element>
        <element>
            <amount>
                <xsl:value-of select="$payroll[4]/amount" />
            </amount>
            <accountNumber>
                <xsl:value-of select="$payroll[4]/accountNumber" />         
            </accountNumber>
        </element>
    </root>
</xsl:template>


如果我正确理解了你的解释,你可以做一些非常简单的事情——即使有点原始:

<xsl:template match="/toPay">
    <xsl:variable name="payroll" select="Pay[payType='PAYROLL']" />
    <root>
        <element>
            <amount>
                <xsl:value-of select="$payroll[1]/amount" />
            </amount>
            <accountNumber>
                <xsl:value-of select="$payroll[1]/accountNumber" />         
            </accountNumber>
        </element>
        <element>
            <amount>
                <xsl:value-of select="$payroll[2]/amount" />
            </amount>
            <accountNumber>
                <xsl:value-of select="$payroll[2]/accountNumber" />         
            </accountNumber>
        </element>
        <element>
            <amount>
                <xsl:value-of select="$payroll[3]/amount" />
            </amount>
            <accountNumber>
                <xsl:value-of select="$payroll[3]/accountNumber" />         
            </accountNumber>
        </element>
        <element>
            <amount>
                <xsl:value-of select="$payroll[4]/amount" />
            </amount>
            <accountNumber>
                <xsl:value-of select="$payroll[4]/accountNumber" />         
            </accountNumber>
        </element>
    </root>
</xsl:template>


我也认为没有必要进行分组,如果您想为那些不存在的元素输出空元素,那么在XSLT 2.0中,您可以使用

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output indent="yes"/>

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

    <xsl:template match="toPay">
        <root>
            <xsl:variable name="payroll" select="Pay[payType = 'PAYROLL']"/>
            <xsl:apply-templates select="$payroll"/>
            <xsl:for-each select="(count($payroll) + 1) to 4">
              <element>
                <amount></amount>
                <accountNumber></accountNumber>
            </element>  
            </xsl:for-each>
        </root>
    </xsl:template>

    <xsl:template match="Pay">
        <element>
            <xsl:apply-templates select="* except payType"/>
        </element>
    </xsl:template>
</xsl:transform>

我也认为没有必要进行分组,如果您想为那些不存在的元素输出空元素,那么在XSLT 2.0中,您可以使用

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output indent="yes"/>

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

    <xsl:template match="toPay">
        <root>
            <xsl:variable name="payroll" select="Pay[payType = 'PAYROLL']"/>
            <xsl:apply-templates select="$payroll"/>
            <xsl:for-each select="(count($payroll) + 1) to 4">
              <element>
                <amount></amount>
                <accountNumber></accountNumber>
            </element>  
            </xsl:for-each>
        </root>
    </xsl:template>

    <xsl:template match="Pay">
        <element>
            <xsl:apply-templates select="* except payType"/>
        </element>
    </xsl:template>
</xsl:transform>


请用文字解释所需的逻辑。我完全不理解您的输出。您的模板创建了一个
结果元素,而您所需的输出没有显示任何此类元素。因此,您需要更详细地解释您想要实现什么。在每个
组中需要四个
元素
元素还是在完整结果中需要四个
元素
结果元素?在输出中应该始终有四个元素节点。每个元素节点都应该填入源xml节点Pay中的值,其中payType是PAYROLL。如果有2个payType为PAYROLL的Pay节点,则输出应该有前2个元素节点,其值来自源xml,其余2个元素节点的amount和account number xml标记为空值。如果有5个Pay节点的payType为PAYROLL怎么办?payType为的Pay节点不会有5个请用文字解释所需的逻辑。我完全不理解您的输出。您的模板创建了一个
结果元素,而您所需的输出没有显示任何此类元素。因此,您需要更详细地解释您想要实现什么。在每个
组中需要四个
元素
元素还是在完整结果中需要四个
元素
结果元素?在输出中应该始终有四个元素节点。每个元素节点都应该填入源xml节点Pay中的值,其中payType是PAYROLL。如果有2个payType为PAYROLL的Pay节点,则输出应该有前2个元素节点,其值来自源xml,其余2个元素节点的amount和account number xml标记为空值。如果有5个Pay节点的payType为PAYROLL怎么办?payType为的Pay节点不会有5个PAYROLL@Vicky如果你的问题得到了回答,请通过接受答案来结束它。@Vicky如果你的问题得到了回答,请通过接受答案来结束它。