2013-04-15 3 views
1

Я немного новичок в XSLT, но я пытаюсь объединить дочерние элементы узлов-сестер в один узел, содержащий все данные.XSLT: Объединить дочерние элементы узлов-браков

Так, например, моя структура данных выглядит следующим образом:

<root> 
    <item> 
     <child index="0"> 
      <data>fooA</data> 
      <data>fooB</data> 
      <data>fooC</data> 
      <data>fooD</data> 
     </child> 
     <child index="1"> 
      <data>foo1</data> 
      <data>foo2</data> 
      <data>foo3</data> 
      <data>foo4</data> 
     </child> 
    </item> 
    <item> 
     <child index="0"> 
      <data>barE</data> 
      <data>barF</data> 
      <data>barG</data> 
      <data>barH</data> 
     </child> 
     <child index="1"> 
      <data>bar5</data> 
      <data>bar6</data> 
      <data>bar7</data> 
      <data>bar8</data> 
     </child> 
    </item> 
</root> 

и я хочу, чтобы преобразовать его так:

<root> 
    <item> 
     <child index="0"> 
      <data>fooA</data> 
      <data>fooB</data> 
      <data>fooC</data> 
      <data>fooD</data> 
      <data>barE</data> 
      <data>barF</data> 
      <data>barG</data> 
      <data>barH</data> 
     </child> 
     <child index="1"> 
      <data>foo1</data> 
      <data>foo2</data> 
      <data>foo3</data> 
      <data>foo4</data> 
      <data>bar5</data> 
      <data>bar6</data> 
      <data>bar7</data> 
      <data>bar8</data> 
     </child> 
    </item> 
</root> 

Так что я думаю, что надо как-то группу по индексу и то просто выберите каждый элемент, но я не совсем уверен, как это сделать.

Заранее спасибо ...

+0

Было бы трудно сделать повсеместно. Вы хотите группировать атрибут индекса или быть n-м дочерним элементом из двух элементов? – Nux

+0

Атрибут индекса. – rybl

ответ

2

Это может работать или, по крайней мере, дать вам начать:

<xsl:for-each select="//item[1]/child"> 
    <xsl:element name="child"> 
     <xsl:attribute name="index"><xsl:value-of select="@index" /></xsl:attribute> 
     <xsl:for-each select="//item/child[@[email protected]]/*"> 
      <xsl:copy-of select="."/> 
     </xsl:for-each> 
    </xsl:element> 
</xsl:for-each> 

Но XSL вообще не является лучше всего подходит для параметризованных операций. Если interal for не будет работать, вы также можете попробовать xsl:call-template запустите with param.

Также обратите внимание, что xsl:copy не работает со слишком большим количеством XSL-двигателей, поэтому вам может потребоваться использовать что-то еще (например, используйте apply-templates и напишите шаблоны для своих элементов).

0

В итоге я использовал Muenchian Grouping, который хорошо работал для меня.

+1

Хотя это теоретически может ответить на вопрос, [было бы предпочтительнее] (// meta.stackoverflow.com/q/8259) включить сюда основные части ответа и предоставить ссылку для справки. –

0

Пример Muenchian Группирование ...

XML Input

<root> 
    <item> 
     <child index="0"> 
      <data>fooA</data> 
      <data>fooB</data> 
      <data>fooC</data> 
      <data>fooD</data> 
     </child> 
     <child index="1"> 
      <data>foo1</data> 
      <data>foo2</data> 
      <data>foo3</data> 
      <data>foo4</data> 
     </child> 
    </item> 
    <item> 
     <child index="0"> 
      <data>barE</data> 
      <data>barF</data> 
      <data>barG</data> 
      <data>barH</data> 
     </child> 
     <child index="1"> 
      <data>bar5</data> 
      <data>bar6</data> 
      <data>bar7</data> 
      <data>bar8</data> 
     </child> 
    </item> 
</root> 

XSLT 1,0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:key name="childByIndex" match="child" use="@index"/> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/root"> 
    <root> 
     <item> 
     <xsl:for-each select="item/child[count(.|key('childByIndex',@index)[1])=1]"> 
      <child> 
      <xsl:apply-templates select="@*|key('childByIndex',@index)/*"/> 
      </child> 
     </xsl:for-each> 
     </item> 
    </root> 
    </xsl:template> 

</xsl:stylesheet> 

XML Output

<root> 
    <item> 
     <child index="0"> 
     <data>fooA</data> 
     <data>fooB</data> 
     <data>fooC</data> 
     <data>fooD</data> 
     <data>barE</data> 
     <data>barF</data> 
     <data>barG</data> 
     <data>barH</data> 
     </child> 
     <child index="1"> 
     <data>foo1</data> 
     <data>foo2</data> 
     <data>foo3</data> 
     <data>foo4</data> 
     <data>bar5</data> 
     <data>bar6</data> 
     <data>bar7</data> 
     <data>bar8</data> 
     </child> 
    </item> 
</root> 

Working Example

Смежные вопросы