XSLT дубликаты элементов в иерархии трансфомации - PullRequest
0 голосов
/ 05 июня 2018

Я новичок в форуме, так что простите меня за некоторую ошибку стиля и языка, не являющегося английским.Моя проблема в том, что у меня есть вывод в xml из выбора на БД, и я хотел бы преобразовать, xslt, эту плоскую структуру в иерархическую структуру.Мой xslt работает нормально и правильно выполняет иерархию, но есть проблема, которая дублирует все элементы и делает, что копирует корневой элемент:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:nsc="http://eos.mcr.com/cdc/anagrafica/ds" version="1.0">
<xsl:key match="/nsc:cdcDbSet/nsc:cdcEntity" name="nodeChildren" use="nsc:idCdcParent"/>
<xsl:variable name="root" select="/nsc:cdcDbSet/nsc:cdcEntity/nsc:idCdcParent"/>
<xsl:template match="nsc:cdcDbSet">
    <cdcList xmlns="http://ws.apache.org/ns/synapse">
        <xsl:apply-templates select="nsc:cdcEntity[nsc:idCdcParent=$root]"/>
    </cdcList>
</xsl:template>
<xsl:template match="nsc:cdcEntity">
    <cdc xmlns="http://ws.apache.org/ns/synapse">
        <idCdc>
            <xsl:value-of select="nsc:idCdc"/>
        </idCdc>
        <idCdcParent>
            <xsl:value-of select="nsc:idCdcParent"/>
        </idCdcParent>
        <cdcName>
            <xsl:value-of select="nsc:cdcName"/>
        </cdcName>
        <order>
            <xsl:value-of select="nsc:order"/>
        </order>
        <isUsed>
            <xsl:value-of select="nsc:isUsed"/>
        </isUsed>
        <cdcList>
            <xsl:apply-templates select="key('nodeChildren',nsc:idCdc)"/>
        </cdcList>
    </cdc>
</xsl:template>
</xsl:stylesheet>

и это преобразованный xml:

<cdcList xmlns="http://ws.apache.org/ns/synapse"
         xmlns:nsc="http://eos.mcr.com/cdc/anagrafica/ds">
   <cdc>
      <idCdc>17</idCdc>
      <idCdcParent>5</idCdcParent>
      <cdcName>testGP</cdcName>
      <order>1</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>15</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>Caserta</cdcName>
      <order>1</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>14</idCdc>
            <idCdcParent>15</idCdcParent>
            <cdcName>testMOD</cdcName>
            <order>4</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
      </cdcList>
   </cdc>
   <cdc>
      <idCdc>5</idCdc>
      <idCdcParent>2</idCdcParent>
      <cdcName>Progetti</cdcName>
      <order>2</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>17</idCdc>
            <idCdcParent>5</idCdcParent>
            <cdcName>testGP</cdcName>
            <order>1</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
         <cdc>
            <idCdc>18</idCdc>
            <idCdcParent>5</idCdcParent>
            <cdcName>testGPS</cdcName>
            <order>2</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
         <cdc>
            <idCdc>6</idCdc>
            <idCdcParent>5</idCdcParent>
            <cdcName>EOS</cdcName>
            <order>3</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
      </cdcList>
   </cdc>
   <cdc>
      <idCdc>16</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>testGP</cdcName>
      <order>2</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>18</idCdc>
      <idCdcParent>5</idCdcParent>
      <cdcName>testGPS</cdcName>
      <order>2</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>11</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>figlio</cdcName>
      <order>2</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>10</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>pippo</cdcName>
      <order>3</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>6</idCdc>
      <idCdcParent>5</idCdcParent>
      <cdcName>EOS</cdcName>
      <order>3</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>3</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>Milano</cdcName>
      <order>4</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>7</idCdc>
            <idCdcParent>3</idCdcParent>
            <cdcName>l</cdcName>
            <order>4</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
      </cdcList>
   </cdc>
   <cdc>
      <idCdc>7</idCdc>
      <idCdcParent>3</idCdcParent>
      <cdcName>l</cdcName>
      <order>4</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>14</idCdc>
      <idCdcParent>15</idCdcParent>
      <cdcName>testMOD</cdcName>
      <order>4</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>8</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>pippo</cdcName>
      <order>5</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>4</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>Napoli</cdcName>
      <order>5</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>9</idCdc>
            <idCdcParent>4</idCdcParent>
            <cdcName>cccc</cdcName>
            <order>6</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
      </cdcList>
   </cdc>
   <cdc>
      <idCdc>9</idCdc>
      <idCdcParent>4</idCdcParent>
      <cdcName>cccc</cdcName>
      <order>6</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>

Как видите, некоторые элементы повторяются, и я хотел бы удалить их,Например, элемент cdc с idCdc = 17 находится под cdcList и под cdc с idCdc = 5. Я попытался изменить xslt без хорошего результата.Спасибо всем, кто пытается помочь мне.

Ps: я ожидаю увидеть что-то вроде этого:

    <cdcList xmlns="http://ws.apache.org/ns/synapse" xmlns:nsc="http://eos.mcr.com/cdc/anagrafica/ds">
   <cdc>
      <idCdc>1</idCdc>
      <idCdcParent>0</idCdcParent>
      <cdcName>Roma</cdcName>
      <order>1</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>4</idCdc>
            <idCdcParent>1</idCdcParent>
            <cdcName>testMOD</cdcName>
            <order>4</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
         <cdc>
            <idCdc>5</idCdc>
            <idCdcParent>1</idCdcParent>
            <cdcName>testMOD</cdcName>
            <order>4</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
         <cdc>
            <idCdc>6</idCdc>
            <idCdcParent>1</idCdcParent>
            <cdcName>testMOD</cdcName>
            <order>4</order>
            <isUsed>false</isUsed>
            <cdcList>
                <cdc>
                    <idCdc>7</idCdc>
                    <idCdcParent>6</idCdcParent>
                    <cdcName>testMODChild</cdcName>
                    <order>4</order>
                    <isUsed>false</isUsed>
                    <cdcList/>
                </cdc>
            </cdcList>
         </cdc>
      </cdcList>
   </cdc>
   <cdc>
      <idCdc>2</idCdc>
      <idCdcParent>0</idCdcParent>
      <cdcName>Progetti</cdcName>
      <order>2</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>8</idCdc>
            <idCdcParent>2</idCdcParent>
            <cdcName>testGP</cdcName>
            <order>1</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
         <cdc>
            <idCdc>9</idCdc>
            <idCdcParent>2</idCdcParent>
            <cdcName>testGPS</cdcName>
            <order>2</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
         <cdc>
            <idCdc>10</idCdc>
            <idCdcParent>2</idCdcParent>
            <cdcName>EOS</cdcName>
            <order>3</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
      </cdcList>
   </cdc>
   <cdc>
      <idCdc>3</idCdc>
      <idCdcParent>0</idCdcParent>
      <cdcName>Milano</cdcName>
      <order>4</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>11</idCdc>
            <idCdcParent>3</idCdcParent>
            <cdcName>l</cdcName>
            <order>4</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
      </cdcList>
   </cdc>
</cdcList>

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Эта трансформация работает очень хорошо, но если я хотел вывод без элемента cdc и с квадратными скобками в каждом cdcList, как этот?

{
"cdcList": [{
        "idCdc": 2,
        "idCdcParent": null,
        "cdcName": "Roma",
        "order": 1,
        "isUsed": false,
        "cdcList": [{
            "idCdc": 5,
            "idCdcParent": 2,
            "cdcName": "Progetti",
            "order": 2,
            "isUsed": false,
            "cdcList": [{
                    "idCdc": 17,
                    "idCdcParent": 5,
                    "cdcName": "testGP",
                    "order": 1,
                    "isUsed": false,
                    "cdcList": null
                },
                {
                    "idCdc": 18,
                    "idCdcParent": 5,
                    "cdcName": "testGPS",
                    "order": 2,
                    "isUsed": false,
                    "cdcList": null
                }
            ]



        }]
    },
    {
        "idCdc": 3,
        "idCdcParent": null,
        "cdcName": "Milano",
        "order": 4,
        "isUsed": false,
        "cdcList": [{

            "idCdc": 7,
            "idCdcParent": 3,
            "cdcName": "l",
            "order": 4,
            "isUsed": false,
            "cdcList": null
        }]
    },
    {
        "idCdc": 4,
        "idCdcParent": null,
        "cdcName": "Napoli",
        "order": 5,
        "isUsed": false,
        "cdcList": [{

            "idCdc": 9,
            "idCdcParent": 4,
            "cdcName": "cccc",
            "order": 6,
            "isUsed": false,
            "cdcList": null
        }]
    }
]

}

Мне нужно реализоватьэтому json в Angular5 и библиотеке компонентов дерева нужен этот формат вывода

0 голосов
/ 05 июня 2018

Ваша ошибка здесь:

<xsl:variable name="root" select="/nsc:cdcDbSet/nsc:cdcEntity/nsc:idCdcParent"/>

При этом не выбирается ни один узел, не говоря уже о корневом узле, или даже идентификатор корневого узла.

Выбирает все <nsc:idCdcParent> элементов.Вместе с этим

<xsl:apply-templates select="nsc:cdcEntity[nsc:idCdcParent=$root]"/>

, где [nsc:idCdcParent=$root] всегда верно, потому что все <nsc:idCdcParent> находятся в $root, а рекурсивный шаг

<xsl:apply-templates select="key('nodeChildren',nsc:idCdc)"/>

Вы просматриваете входной документнесколько раз, что приводит к дублированию вывода.


Предполагая, что корневой узел имеет идентификатор 1, это создает правильно вложенное дерево.

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:nsc="http://eos.mcr.com/cdc/anagrafica/ds"
    xmlns="http://ws.apache.org/ns/synapse"
    exclude-result-prefixes="nsc"
>
    <xsl:output indent="yes" />
    <xsl:key name="nodesByParent" match="nsc:cdcEntity" use="nsc:idCdcParent"/>

    <xsl:template match="nsc:cdcDbSet">
        <cdcList>
            <xsl:apply-templates select="key('nodesByParent', 1)"/>
        </cdcList>
    </xsl:template>

    <xsl:template match="nsc:cdcEntity">
        <cdc>
            <xsl:apply-templates mode="copy-local" select="
                nsc:idCdc|nsc:idCdcParent|nsc:cdcName|nsc:order|nsc:isUsed
            " />
            <cdcList>
                <xsl:apply-templates select="key('nodesByParent', nsc:idCdc)"/>
            </cdcList>
        </cdc>
    </xsl:template>

    <xsl:template match="*" mode="copy-local">
        <xsl:element name="{local-name()}">
            <xsl:value-of select="." />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Примечание

  • объявление xmlns верхнего уровня по умолчанию, поэтому вам не нужно повторяться в теле таблицы стилей
  • атрибут exclude-result-prefixes
  • уменьшает дублирование за счет использованияшаблон для вывода любого элемента с таким же локальным именем

Результат:

<cdcList xmlns="http://ws.apache.org/ns/synapse">
   <cdc>
      <idCdc>15</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>Caserta</cdcName>
      <order>1</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>14</idCdc>
            <idCdcParent>15</idCdcParent>
            <cdcName>testMOD</cdcName>
            <order>4</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
      </cdcList>
   </cdc>
   <cdc>
      <idCdc>16</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>testGP</cdcName>
      <order>2</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>11</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>figlio</cdcName>
      <order>2</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>10</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>pippo</cdcName>
      <order>3</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>3</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>Milano</cdcName>
      <order>4</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>7</idCdc>
            <idCdcParent>3</idCdcParent>
            <cdcName>l</cdcName>
            <order>4</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
      </cdcList>
   </cdc>
   <cdc>
      <idCdc>8</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>pippo</cdcName>
      <order>5</order>
      <isUsed>false</isUsed>
      <cdcList/>
   </cdc>
   <cdc>
      <idCdc>4</idCdc>
      <idCdcParent>1</idCdcParent>
      <cdcName>Napoli</cdcName>
      <order>5</order>
      <isUsed>false</isUsed>
      <cdcList>
         <cdc>
            <idCdc>9</idCdc>
            <idCdcParent>4</idCdcParent>
            <cdcName>cccc</cdcName>
            <order>6</order>
            <isUsed>false</isUsed>
            <cdcList/>
         </cdc>
      </cdcList>
   </cdc>
</cdcList>
...