Преобразование XML с использованием XSLT путем группировки тегов на основе некоторого значения - PullRequest
0 голосов
/ 24 января 2019

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

 <root>
   <item id="100">
      <properties>
         <property attribute-id="parent">10</property>
      </properties>
      <properties>
         <property attribute-id="amount">1.1</property>
      </properties>
   </item>
   <item id="101">
      <properties>
         <property attribute-id="parent">10</property>
      </properties>
      <properties>
         <property attribute-id="amount">1.1</property>
      </properties>
   </item>
   <item id="102">
      <properties>
         <property attribute-id="parent">11</property>
      </properties>
      <properties>
         <property attribute-id="amount">1.1</property>
      </properties>
   </item>
   <item id="103">
      <properties>
         <property attribute-id="parent">10</property>
      </properties>
      <properties>
         <property attribute-id="amount">1.1</property>
      </properties>
   </item>
   <item id="104">
      <properties>
         <property attribute-id="parent">11</property>
      </properties>
      <properties>
         <property attribute-id="amount">1.1</property>
      </properties>
   </item>
</root>

Новый тег должен быть:

<item id = "10">  
       <childs>
         <child id="100" />
         <child id="101" />
         <child id="102" />
       </childs>
    </item>       
    <item id = "11">
       <childs>
         <child id="104" />
         <child id="105" />
       </childs>
    </item> 

Возможно ли это с XSLT?
Как это можно сделать в XSLT?

Редактирование исходного сообщения. Я столкнулся с некоторыми проблемами, когда тег был в формате атрибута. Попытка обновления первого решения, но форма атрибута вызывает много проблем.

1 Ответ

0 голосов
/ 24 января 2019

Вы можете добиться с помощью этого метода XSLT-1.0 Muenchian Grouping . Если вы ищете на SO, вы найдете много примеров. Применяя этот метод, ваша таблица стилей может выглядеть следующим образом (я добавил гипотетический элемент <root> вокруг исходного XML, чтобы сделать его правильно сформированным ):

xsl:key и выражение select внешнего xsl:for-each реализуют мюнхенскую группировку . Внутренняя часть цикла должна быть своего рода , требующей объяснения.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="id" match="item" use="properties/property[@attribute-id='parent']" />   

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each select="item[generate-id() = generate-id(key('id',properties/property[@attribute-id='parent'])[1])]">
            <item id="{parent}">
                <childs>
                    <xsl:for-each select="key('id',properties/property[@attribute-id='parent'])">
                        <child id="{@id}" />
                    </xsl:for-each>
                </childs>
            </item>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Если вы можете использовать XSLT-2.0 или выше, вы можете использовать xsl:for-each-group следующим образом:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each-group select="item" group-by="properties/property[@attribute-id='parent']">
            <item id="{parent}">
                <childs>
                    <xsl:for-each select="current-group()">
                        <child id="{@id}" />
                    </xsl:for-each>
                </childs>
            </item>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Это немного проще, но делает то же самое.


Его выход в обоих случаях:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <item id="">
      <childs>
         <child id="100"/>
         <child id="101"/>
         <child id="103"/>
      </childs>
   </item>
   <item id="">
      <childs>
         <child id="102"/>
         <child id="104"/>
      </childs>
   </item>
</root>

Это не совсем то, что вы хотите, но я думаю, что последние child идентификаторы вашего примера неверны.

...