首页 > 解决方案 > 使用嵌套的 For Each 和 If 从不同的子节点返回节点值

问题描述

当“信用卡”是付款方式之一时,我正在尝试提取邮政编码。通常有多种支付方式,即信用卡和现金;信用卡和礼品卡;等等。信用卡不一定是第一次付款,但绝不会有允许使用多张信用卡的情况。我想遍历所有支付类型,当支付类型值为“CreditCard”时,然后检索邮政编码。如果未使用信用卡,则该值应为空。

根据我最初的研究,看起来我需要一个嵌套的 For-Each,但不一定是一个 IF。我发现了大量解释嵌套 for-each 语句的文章和显示简单 if 语句的文章。我还没有找到任何明确的文章显示使用这些组合语句从不同的节点级别进行检索。这是我的这一行的伪代码:

如果...购买/购买/付款/付款/类型 = 'CreditCard'
那么...购买/购买/付款/付款/地址/邮政编码的价值

我尝试过的各种版本在 SSIS 包中都没有失败,但没有检索到结果。

XML 示例:

<?xml version="1.0" encoding="utf-8"?>
<exportbatch xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<purchases>
    <purchase>
        <posRef>987654321</posRef>
        <locationRef>1234</locationRef>
        <totalamount>99.9900</totalamount>
        <payments>
            <payment>
                <amount>50.0000</amount>
                <description>Gift Card x-8765</description>
                <type>GiftCard</type>
            </payment>
            <payment>
                <amount>19.5200</amount>
                <description>some credit card brand x-8765</description>
                <brand>some credit card brand</brand>
                <type>CreditCard</type>
                <address>
                    <zipcode>65432</zipcode>
                </address>
            </payment>
        </payments>
    </purchase>
</purchases>
</exportbatch>  

XSLT 示例:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="exportbatch">
    <purchases>
    <xsl:for-each select="purchases/purchase">
        <purchase>
            <posRef><xsl:value-of select="posRef"/></posRef>
            <LocationId><xsl:value-of select="locationRef"/></LocationId>
            <TotalAmount><xsl:value-of select="totalamount"/></TotalAmount>
            <xsl:for-each select="payments/payment/type">
                <xsl:if test="'CreditCard'">
                    <PaymentZipCode><xsl:value-of select="address/zipcode"/></PaymentZipCode>
                </xsl:if>
            </xsl:for-each>
        </purchase>
    </xsl:for-each>
    </purchases>
</xsl:template>
</xsl:stylesheet>

备用 XSLT 示例:

    <xsl:for-each select="payments/payment">
        <xsl:if test="@type='CreditCard'">
            <PaymentZipCode><xsl:value-of select="address/zipcode"/></PaymentZipCode>
        </xsl:if>
    </xsl:for-each>

标签: xmlxsltxslt-1.0

解决方案


我认为你可以这样做:

<xsl:template match="exportbatch">
    <purchases>
        <xsl:for-each select="purchases/purchase">
            <purchase>
                <posRef><xsl:value-of select="posRef"/></posRef>
                <LocationId><xsl:value-of select="locationRef"/></LocationId>
                <TotalAmount><xsl:value-of select="totalamount"/></TotalAmount>
                <xsl:variable name="cc" select="payments/payment[type='CreditCard']" />
                <xsl:if test="$cc">
                    <PaymentZipCode><xsl:value-of select="$cc/address/zipcode"/></PaymentZipCode>
                </xsl:if>
            </purchase>
        </xsl:for-each>
    </purchases>
</xsl:template>

这将测试payment其类型是否CreditCard存在 - 如果存在,它会从那里检索邮政编码。

或者,您可以这样做:

<xsl:template match="exportbatch">
    <purchases>
        <xsl:for-each select="purchases/purchase">
            <purchase>
                <posRef><xsl:value-of select="posRef"/></posRef>
                <LocationId><xsl:value-of select="locationRef"/></LocationId>
                <TotalAmount><xsl:value-of select="totalamount"/></TotalAmount>
                <xsl:if test="payments/payment[type='CreditCard']">
                    <PaymentZipCode><xsl:value-of select="payments/payment/address/zipcode"/></PaymentZipCode>
                </xsl:if>
            </purchase>
        </xsl:for-each>
    </purchases>
</xsl:template>

这执行相同的测试,如果它通过,它会检索它可以找到的第一个邮政编码。


推荐阅读