Использование nested For Each и If для возврата значения узла из другого дочернего узла - PullRequest
0 голосов
/ 16 октября 2019

Я пытаюсь извлечь почтовый индекс, когда «Кредитная карта» является одним из способов оплаты. Часто существует несколько способов оплаты, например, Кредитная карта и наличные;Кредитная карта и подарочная карта;и т. д. Кредитная карта не обязательно является первым платежом, но никогда не допускается использование более одной кредитной карты. Я хочу просмотреть все типы платежей, и когда значение типа платежа равно «Кредитная карта», получить почтовый индекс. Если кредитные карты не используются, значение должно быть нулевым.

Исходя из моего первоначального исследования, похоже, мне нужен вложенный For-Each, но не обязательно IF. Я нашел много статей, которые объясняют вложенные для каждого утверждения и статьи, которые показывают простые операторы 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>

1 Ответ

0 голосов
/ 16 октября 2019

Я думаю, что вы могли бы сделать:

<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>

Это делает тот же тест, и если он проходит, он получает первый найденный почтовый индекс.

...