Условно для каждого в XSLT - PullRequest
       7

Условно для каждого в XSLT

0 голосов
/ 17 сентября 2018

Требуется ваша помощь для проверки правильности приведенного ниже кода XSLT.

Мой входной XML будет выглядеть следующим образом.

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
    <Worker>
        <Batch_number>1234</Batch_number>
        <Assignment>
            <type>A</type>
            <name>New York</name>
        </Assignment>
        <Assignment>
            <type>A</type>
            <name>Boston</name>
        </Assignment>
        <Assignment>
            <type>A</type>
            <name>Boston</name>
        </Assignment>
        <Assignment>
            <type>A</type>
            <name>Boston</name>
        </Assignment>
        <Assignment>
            <type>B</type>
            <name>Chicago</name>
        </Assignment>
    </Worker>
</Workers>

Мой выходной файл должен выглядеть ниже после преобразования

    <?xml version="1.0" encoding="UTF-8"?>
<Update_Data>
    <Records>
        <Batch_number>1234</Batch_number>
        <Record_Location>
            <Location>
                <order>1</order>
                <name>New York</name>
            </Location>
            <Location>
                <order>2</order>
                <name>Boston</name>
            </Location>
            <Location>
                <order>3</order>
                <name>Boston</name>
            </Location>
            <Location>
                <order>4</order>
                <name>Boston</name>
            </Location>
        </Record_Location>
        <Record_Location>
            <Location>
                <order>1</order>
                <name>Chicago</name>
            </Location>
        </Record_Location>
    </Records>
</Update_Data>

Я написал следующее XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <Update_Data>
            <Records>
                <Batch_number><xsl:value-of select="Workers/Worker/Batch_number"/></Batch_number>
                    <Record_Location>
                        <xsl:for-each select="Workers/Worker/Assignment[type='A']">

                            <Location>
                                <order>
                                    <xsl:value-of select="position()"/>
                                </order>
                                <name>
                                    <xsl:value-of select="name"/>
                                </name>
                            </Location>
                        </xsl:for-each>
                        </Record_Location>
                        <xsl:for-each select="Workers/Worker/Assignment[type='B']">
                        <Record_Location>
                        <Location>
                                <order>
                                    <xsl:value-of select="position()"/>
                                </order>
                                <name>
                                    <xsl:value-of select="name"/>
                                </name>
                            </Location>
                            </Record_Location>
                            </xsl:for-each>
            </Records>
        </Update_Data>
    </xsl:template>
</xsl:stylesheet>

Требования к преобразованию.

Если значение равно и оно появляется несколько раз во входном XML, элементы Location (под тегом Record_Location) должны создаваться столько раз, сколько существует в файле с соответствующими значениями.

для .eg <type> - это A, появляющийся 4 раза во входном XML, поэтому необходимо создать четыре элемента <Location>, тег должен содержать последовательное значение.

<type> означает, что B появляется только один раз, поэтому в выходном файле должен присутствовать только один элемент.

Количество <Record_Location> элементов в выходных данных должно совпадать с уникальными значениями<type>.В моем примере присутствуют только два уникальных значения, то есть A и B, поэтому мой вывод должен содержать только два <Record_Location>

XSLT-кода, которые я написал, дает ожидаемый результат.Но я не уверен, что это эффективный способ написания кода для моего требования.Есть ли способ консолидировать условия для каждого, не указав type = 'A' или type = 'B' и т. Д. Входной XML может содержать несколько различных типов.Или даже можно написать код без for-each цикла

Может кто-нибудь взглянуть на это и предложить лучший подход, пожалуйста?

- спасибо Anoop


После включения предложения Мартина в XSLT ... я получил что-то вроде ниже.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <Update_Data>
            <Records>
                <Batch_number>
                    <xsl:value-of select="Workers/Worker/Batch_number"/>
                </Batch_number>
                <xsl:for-each-group select="Workers/Worker/Assignment" group-by="type">
                    <Record_Location>
                        <xsl:apply-templates select="current-group()"/>
                    </Record_Location>
                </xsl:for-each-group>
            </Records>
        </Update_Data>
    </xsl:template>
    <xsl:template match="Assignment">
        <Location>
            <order>
                <xsl:value-of select="position()"/>
            </order>
            <name>
                <xsl:apply-templates select="name"/>
            </name>
        </Location>
    </xsl:template>
</xsl:stylesheet>
...