2013-05-13 3 views
0

у меня есть что-то вроде этого:Как к группе соседних братьев и сестер

<root> 
    <a>foo</a> 
    <b>bar</b> 
    <groupme>foobar</groupme> 
    <groupme>baz</groupme> 
    <groupme>42</groupme> 
    <c>abc</c> 
    <d>def</d> 
    <groupme>foo</groupme> 
    <x>xyz</x> 
    <groupme>bar</groupme> 
    <groupme>foo</groupme> 
    <z>thats it</z> 
</root> 

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

<root> 
    <a>foo</a> 
    <b>bar</b> 
    <groupme>foobar baz 42</groupme> 
    <c>abc</c> 
    <d>def</d> 
    <groupme>foo</groupme> 
    <x>xyz</x> 
    <groupme>bar foo</groupme> 
    <z>thats it</z> 
</root> 

также на GroupMe узлы, содержащие другие узлы, я просто оставлю их, чтобы предоставить простой пример. узлы groupme отображаются только на определенном уровне, а в других узлах нет узлов, а затем root.

любая помощь для меня?

+0

Dirk, помогает ли найденный код решить проблему? –

ответ

0

Такая группировка может быть достигнута с помощью подхода, называемого «родственных рекурсиями», для вашей проблемы, я хотел бы предложить таблицу стилей следующим образом:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/> 

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

<xsl:template match="root/groupme[not(preceding-sibling::*[1][self::groupme])]"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()"/> 
    <xsl:apply-templates select="following-sibling::*[1][self::groupme][1]" mode="list"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="root/groupme[preceding-sibling::*[1][self::groupme]]"/> 


<xsl:template match="root/groupme[preceding-sibling::*[1][self::groupme]]" mode="list"> 
    <xsl:text> </xsl:text> 
    <xsl:apply-templates select="node()"/> 
    <xsl:apply-templates select="following-sibling::*[1][self::groupme][1]" mode="list"/> 
</xsl:template> 

</xsl:stylesheet> 

При подаче на вход

<root> 
    <a>foo</a> 
    <b>bar</b> 
    <groupme>foobar</groupme> 
    <groupme>baz</groupme> 
    <groupme>42</groupme> 
    <c>abc</c> 
    <d>def</d> 
    <groupme>foo</groupme> 
    <x>xyz</x> 
    <groupme>bar</groupme> 
    <groupme>foo</groupme> 
    <z>thats it</z> 
</root> 

Результата is

<root> 
    <a>foo</a> 
    <b>bar</b> 
    <groupme>foobar baz 42</groupme> 
    <c>abc</c> 
    <d>def</d> 
    <groupme>foo</groupme> 
    <x>xyz</x> 
    <groupme>bar foo</groupme> 
    <z>thats it</z> 
</root> 

В качестве альтернативы рекурсии сестры также возможно «захватить», следующие братья и сестры с основанием на основе ключевых слов:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/> 

<xsl:key 
    name="first" 
    match="root/groupme[preceding-sibling::*[1][self::groupme]]" 
    use="generate-id(preceding-sibling::groupme[not(preceding-sibling::*[1][self::groupme])][1])"/> 

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

<xsl:template match="root/groupme[not(preceding-sibling::*[1][self::groupme])]"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()"/> 
    <xsl:apply-templates select="key('first', generate-id())" mode="list"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="root/groupme[preceding-sibling::*[1][self::groupme]]"/> 

<xsl:template match="root/groupme" mode="list"> 
    <xsl:text> </xsl:text> 
    <xsl:apply-templates select="node()"/> 
</xsl:template> 

</xsl:stylesheet> 

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

  • Нет связанных вопросов^_^