Необходимо создать XML на основе другого XML с использованием XSLT2.0 на основе различных атрибутов и сгруппировать по - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь сгенерировать XML на основе 2 других XML. Я опрашиваю БД, которая возвращает данные о людях (в запросе может быть n человек). Конечный XML должен иметь точное количество тегов данных в качестве отдельных тегов имен в XML, поступающих из DB . Например:

1-й XML - Получение этого из БД

<parent>
    <child>
        <name>John</name>
        <city>Boston</city>
    </child>
    <child>
        <name>John</name>
        <city>Seattle</city>
    </child>
    <child>
        <name>Allison</name>
        <city>Houston</city>
    </child>
    <child>
        <name>John</name>
        <city>Boston</city>
    </child>
</parent>

2-й XML - Получение этого из другого источника

<details>
    <detail>
        <city>Boston</city>
        <code>abc</code>
    </detail>
    <detail>
        <city>Houston</city>
        <code>xyz</code>
    </detail>
</details>

Сначала мне нужно создайте 2 тега данных, так как есть 2 разных имени (Джон и Эллисон), а затем мне нужно проверить одно за другим, если тег City для всех тегов child в 1-м XML соответствует во 2-м XML, а затем создает Сведения Пометить и скопировать Код Пометить и его значение в Финале XML.

1) Если нет подходящих записей, тег подробностей создавать не следует, так как нет подходящих записей. 2) Нет, никогда не будет нескольких подходящих записей. Тег данных должен быть создан на основе тегов Distinct NAME и тегов сведений, основанных на количестве соответствующих тегов города.

Окончательный XML, который будет создан

<FinalData>
    <Data>
        <name>John</name>
        <details>
            <city>Boston</city>
            <code>xyz</code>
        </details>
    </Data>
    <Data>
        <name>Allison</name>
        <details>
            <city>Houston</city>
            <code>abc</code>
        </details>
    </Data>
</FinalData>

РЕДАКТИРОВАТЬ 1:

Я сталкиваюсь с проблемами при заполнении кодового тега , так как мне нужно сопоставить тег city в обоих XML-файлах и мне нужно для l oop для сопоставления.

Ниже приведена моя попытка -

<?xml version="1.0" encoding="UTF-8"?>
<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:param name="otherFile" select="document('SOF Input 2.xml')"/>
    <xsl:template match="parent">
        <FinalData>
            <xsl:for-each-group select="child" group-by="name">
                <data>
                    <name>
                        <xsl:value-of select="name"/>
                    </name>
                    <details>
                        <city>
                            <xsl:value-of select="city"/>
                        </city>
                        <code>
                            <xsl:for-each select="$otherFile/details/detail">
                                <xsl:if test="parent/child/city='/city'">
                                    <!--I am getting stuck here - not able to get value here..i guess both city tags are referring to the same-->
                                    <xsl:value-of select="/code"/>
                                </xsl:if>
                            </xsl:for-each>
                        </code>
                    </details>
                </data>
                <xsl:text>
</xsl:text>
            </xsl:for-each-group>
        </FinalData>
    </xsl:template>
</xsl:stylesheet>

Я получаю следующий вывод с этим -

<?xml version="1.0" encoding="UTF-8"?>
<FinalData><data>
        <name>John</name>
        <details>
            <city>Boston</city>
            <code/>
        </details>
    </data>
<data>
        <name>Allison</name>
        <details>
            <city>Houston</city>
            <code/>
        </details>
    </data>
</FinalData>

Также немного ошибочно с отступом. Дайте мне знать, если я что-то пропустил.

РЕДАКТИРОВАТЬ 2:

Боюсь, что сценарий, упомянутый Майклом, пришел намного раньше, чем ожидалось. Тег city будет повторяться, но под тегом parent . Значения тега city будут уникальными в теге parent . Я должен взять значения из всех совпадающих тегов city , один за другим, по всем родителям и заполнить таким образом, чтобы все совпадения в теге parent помещались в соответствующие тег в выводе XML. PFB образец XML, который объяснил бы лучше -

1st XML -

<parent>
    <child>
        <name>John</name>
        <city>Boston</city>
    </child>
    <child>
        <name>John</name>
        <city>Seattle</city>
    </child>
    <child>
        <name>Allison</name>
        <city>Houston</city>
    </child>
    <child>
        <name>John</name>
        <city>Boston</city>
    </child>
</parent>

2nd XML -

<details>
    <parent>
        <detail>
            <city>Boston</city>
            <code>abc</code>
        </detail>
        <detail>
            <city>Houston</city>
            <code>xyz</code>
        </detail>
    </parent>
    <parent>
        <detail>
            <city>Boston</city>
            <code>abc</code>
        </detail>
        <detail>
            <city>Seattle</city>
            <code>mno</code>
        </detail>
    </parent>
    <parent>
        <detail>
            <city>Houston</city>
            <code>xyz</code>
        </detail>
        <detail>
            <city>Seattle</city>
            <code>mno</code>
        </detail>
    </parent>
</details>

Final Expected XML -

<FinalData>
    <Data>
        <name>John</name>
        <details>
            <detail>
                <city value="Boston">abc</city>
            </detail>
            <detail>
                <city value="Boston">abc</city>
                <city value="Seattle">mno</city>
            </detail>
            <detail>
                <city value="Seattle">mno</city>
            </detail>
        </details>
    </Data>
    <Data>
        <name>Allison</name>
        <details>
            <detail>
                <city value="Houston">xyz</city>
            </detail>
            <detail>
                <city value="Houston">xyz</city>
            </detail>
        </details>
    </Data>
</FinalData>

Надеюсь, это понятно, поскольку я не умею давать объяснения.

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

Попробовать таким образом?

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="*"/>

<xsl:param name="otherFile" select="document('SOF Input 2.xml')"/>

<xsl:key name="detail-by-city" match="detail" use="city" />

<xsl:template match="/parent">
    <FinalData>
        <xsl:for-each-group select="child" group-by="name">
            <data>
                <xsl:copy-of select="name"/>
                <xsl:for-each select="key('detail-by-city', current-group()/city, $otherfile)">
                    <details>
                         <xsl:copy-of select="*"/>
                    </details>
                </xsl:for-each>
            </data>
        </xsl:for-each-group>
    </FinalData>
</xsl:template>

</xsl:stylesheet>

Предполагается, что группа может иметь более одной соответствующей записи в другом документе, и вы хотите создать отдельный details узел для каждого из них.

0 голосов
/ 07 апреля 2020

Объявите ключ

<xsl:key name="city" match="detail" use="city"/>

и затем используйте

<xsl:copy-of select="key('city', city, $otherFile)/code"/>

внутри вашего for-each-group для вывода соответствующего кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...