2017-02-14 7 views
0

У меня есть XML, как это:XSLT преобразование (XML в XML)

<object> 
    <string name "order">1<string> 
    <string name "item">1<string> 
</object> 
<object> 
    <string name "order">1<string> 
    <string name "item">2<string> 
</object> 
<object> 
    <string name "order">2<string> 
    <string name "item">1<string> 
</object> 

Я хочу, чтобы преобразовать XML в этом strukture:

<object order=1> 
    <string name "item">1<string> 
    <string name "item">2<string> 
</object> 
<object order=2> 
    <string name "item">1<string> 
</object> 

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

+1

Это * группировка * вопрос. Сделайте поиск - это, вероятно, самый часто задаваемый вопрос XSLT. Обратите внимание, что для XSLT 1.0 или 2.0 разные ответы. –

ответ

0

Первое, что нужно сделать, - привести исходный XML в правильную форму.

  1. XML документ содержит только один корневого тега (назовем его основного) и этот тег может содержать несколько тегов источника (например, объекта).

  2. Каждый тег (как вы написали в строке тегов) может содержать атрибут с значением (в вашем случае имени и порядка), но между ними должен быть «=» знак.

  3. В случае объекта тега вы вспомнили поставить «/» в закрывающий тег, но вы забыли об этом в каждом закрытии строки тега.

Таким образом, правильный входной XML (после того, как необходимые поправки) является:

<main> 
    <object> 
    <string name="order">1</string> 
    <string name="item">1</string> 
    </object> 
    <object> 
    <string name="order">1</string> 
    <string name="item">2</string> 
    </object> 
    <object> 
    <string name="order">2</string> 
    <string name="item">1</string> 
    </object> 
</main> 

Теперь давайте перейдем к основному бизнесу. В описании я поместил номера строк - ссылки на окончательное решение.

Начнет с XSL: выходной отступом = «да» (строка 2), в противном случае все содержимое бы в одной строке (трудной для чтения).

код XML, содержит один tempate соответствия основной тег (строка 4).

Первое, что он делает это копию (открытие и закрытие основные теги - строка 5).

Затем строка 6 содержит цикл группировки (для каждой группы). Объекты сгруппированных являются объектом элементов (см выберите пункт) и группируя ключ содержание строки дочернего тега (относительно текущего объекта) с атрибутом именем равных «заказ» (см group-by).

Так первая группа содержит объекта тегов Нет 1 и 2 (они оба имеют строки имени = «порядок» тег с содержанием «1», а второй группой содержит объекта тега Нет 3.

Тогда (для каждой группы из источника объекта тегов), мы создаем выходной объект элемент (строка 7).

Этот элемент должен иметь ДТО ритона с именем заказать со значением текущей группы группировки (строка 8).

текущий элемент (выход объект) должен содержать данные из каждого элемента в текущей группы, поэтому мы должны написать для-каждого заявления, циклический всех исходного объекта тегов - содержание текущей группы (см. , пункт, строка 9).

В пределах этого цикла, для каждого входного объекта , мы КРИТ в строке элемента (строка 10).

Этот элемент должен иметь атрибут с именем «имя» (см имя дизъюнкцию) и его значение должно быть «пункт» (см выберите пункт) - строка 11.

Последнее, что нужно сделать, это создать содержание выходного тега - значение дочерних строки тега (относительно текущего объекта) с имя атрибута элемента значения - строка 12.

Все дальнейшие строки в XSL являются закрывающими тегами.

Ниже у вас есть полное решение XSL.

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

    <xsl:template match="main"> 
    <xsl:copy> 
     <xsl:for-each-group select="object" group-by="string[@name='order']"> 
     <xsl:element name="object"> 
      <xsl:attribute name="order" select="current-grouping-key()"/> 
      <xsl:for-each select="current-group()"> 
      <xsl:element name="string"> 
       <xsl:attribute name="name" select="'item'"/> 
       <xsl:value-of select="string[@name='item']"/> 
      </xsl:element> 
      </xsl:for-each> 
     </xsl:element> 
     </xsl:for-each-group> 
    </xsl:copy> 
    </xsl:template> 

</xsl:transform> 
Смежные вопросы