XSLT для преобразования плоской структуры в многоуровневую структуру - PullRequest
0 голосов
/ 09 июля 2020

У меня есть XML, который выглядит так:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Report>
    <BCOT>
        <Detail_Collection>
            <Detail>
                <ElementId>Element1</ElementId>
                <ParentElementId>Element0</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element2</ElementId>
                <ParentElementId>Element1</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element3</ElementId>
                <ParentElementId>Element2</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element4</ElementId>
                <ParentElementId>Element3</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element5</ElementId>
                <ParentElementId>Element3</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element6</ElementId>
                <ParentElementId>Element1</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element7</ElementId>
                <ParentElementId>Element6</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element8</ElementId>
                <ParentElementId>Element7</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element9</ElementId>
                <ParentElementId>Element8</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element10</ElementId>
                <ParentElementId>Element9</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element11</ElementId>
                <ParentElementId>Element10</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element12</ElementId>
                <ParentElementId>Element11</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element13</ElementId>
                <ParentElementId>Element11</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element14</ElementId>
                <ParentElementId>Element11</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element15</ElementId>
                <ParentElementId>Element9</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element16</ElementId>
                <ParentElementId>Element15</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element17</ElementId>
                <ParentElementId>Element16</ParentElementId>
            </Detail>
            <Detail>
                <ElementId>Element18</ElementId>
                <ParentElementId>Element16</ParentElementId>
            </Detail>
        </Detail_Collection>
    </BOMConsistOfTmp>
</Report>

И мне нужна таблица стилей, чтобы он выглядел так:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Report>
    <BCOT>
        <Detail_Collection>
            <Detail>
                <ElementId>Element1</ElementId>
                <ParentElementId>Element0</ParentElementId>
                <Detail>
                    <ElementId>Element2</ElementId>
                    <ParentElementId>Element1</ParentElementId>
                    <Detail>
                        <ElementId>Element3</ElementId>
                        <ParentElementId>Element2</ParentElementId>
                        <Detail>
                            <ElementId>Element4</ElementId>
                            <ParentElementId>Element3</ParentElementId>
                        </Detail>
                        <Detail>
                            <ElementId>Element5</ElementId>
                            <ParentElementId>Element3</ParentElementId>
                        </Detail>
                    </Detail>
                </Detail>
                <Detail>
                    <ElementId>Element6</ElementId>
                    <ParentElementId>Element1</ParentElementId>
                    <Detail>
                        <ElementId>Element7</ElementId>
                        <ParentElementId>Element6</ParentElementId>
                        <Detail>
                            <ElementId>Element8</ElementId>
                            <ParentElementId>Element7</ParentElementId>
                            <Detail>
                                <ElementId>Element9</ElementId>
                                <ParentElementId>Element8</ParentElementId>
                                <Detail>
                                    <ElementId>Element10</ElementId>
                                    <ParentElementId>Element9</ParentElementId>
                                    <Detail>
                                        <ElementId>Element11</ElementId>
                                        <ParentElementId>Element10</ParentElementId>
                                        <Detail>
                                            <ElementId>Element12</ElementId>
                                            <ParentElementId>Element11</ParentElementId>
                                        </Detail>
                                        <Detail>
                                            <ElementId>Element13</ElementId>
                                            <ParentElementId>Element11</ParentElementId>
                                        </Detail>
                                        <Detail>
                                            <ElementId>Element14</ElementId>
                                            <ParentElementId>Element11</ParentElementId>
                                        </Detail>
                                    </Detail>
                                </Detail>
                                <Detail>
                                    <ElementId>Element15</ElementId>
                                    <ParentElementId>Element9</ParentElementId>
                                    <Detail>
                                        <ElementId>Element16</ElementId>
                                        <ParentElementId>Element15</ParentElementId>
                                        <Detail>
                                            <ElementId>Element17</ElementId>
                                            <ParentElementId>Element16</ParentElementId>
                                        </Detail>
                                        <Detail>
                                            <ElementId>Element18</ElementId>
                                            <ParentElementId>Element16</ParentElementId>
                                        </Detail>
                                    </Detail>
                                </Detail>
                            </Detail>
                        </Detail>
                    </Detail>
                </Detail>
            </Detail>
        </Detail_Collection>
    </BOMConsistOfTmp>
</Report>

Я читал, что это Лучше использовать шаблоны, когда у меня есть рекурсивная задача, но я никогда полностью не понимал шаблоны в отличие от for-each.

Я пробовал использовать стратегию, где я запускаю ее фиксированное количество раз, но Я бы очень хотел, чтобы он работал рекурсивно.

Может мне кто-нибудь помочь?

1 Ответ

1 голос
/ 09 июля 2020

Это легко сделать с помощью ключа для идентификации дочерних элементов каждой детали (а также наличия родителя):

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="parent" match="Detail" use="ElementId" />
<xsl:key name="child" match="Detail" use="ParentElementId" />

<xsl:template match="/Report">
    <Report>
        <BCOT>
            <Detail_Collection>
                <xsl:apply-templates select="BCOT/Detail_Collection/Detail[not(key('parent', ParentElementId))]"/>
            </Detail_Collection>
        </BCOT>
    </Report>
</xsl:template>

<xsl:template match="Detail">
    <xsl:copy>
        <xsl:copy-of select="*"/>
        <xsl:apply-templates select="key('child', ElementId)"/>
    </xsl:copy>
</xsl:template>

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