2013-08-29 2 views
1

Я могу видеть много ответов на подобные вопросы, но я не могу заставить их работать для меня. У меня есть несколько xml-файлов с некоторыми узлами узлов-сестер, имеющих одинаковое имя тега. Я хочу объединить эти узлы с помощью XSLT. Любая помощь будет глубоко оценена.xslt объединить несколько узлов с тем же именем

Вход:

<?xml version="1.0"?> 
<Screen> 
    <Shapes> 
    <Triangle id="tri1"> 
    <color>red</color> 
    <size>large</size> 
    </Triangle> 
    </Shapes> 
    <Shapes> 
    <Rectangle id="rec1"> 
     <color>blue</color> 
     <size>medium</size> 
    </Rectangle> 
    </Shapes> 
    <Shapes> 
    <Circle id="cir1"> 
     <color>green</color> 
     <size>small</size> 
    </Circle> 
    </Shapes> 
    <Shapes> 
    <Square id="sqr1"> 
     <color>yellow</color> 
     <size>large</size> 
    </Square> 
    </Shapes> 
    <Device> 
    <Name>peg</Name> 
    <type>X11</type> 
    </Device> 
    <Utilities> 
    <Software>QT</Software> 
    <Platform>Linux</Platform> 
    </Utilities> 
</Screen> 

Я хочу, чтобы объединить все "Shapes" узлы. Обязательный выход

<?xml version="1.0"?> 
<Screen> 
    <Shapes> 
    <Triangle id="tri1"> 
     <color>red</color> 
     <size>large</size> 
    </Triangle> 

    <Rectangle id="rec1"> 
     <color>blue</color> 
     <size>medium</size> 
    </Rectangle> 

    <Circle id="cir1"> 
     <color>green</color> 
     <size>small</size> 
    </Circle> 

    <Square id="sqr1"> 
     <color>yellow</color> 
     <size>large</size> 
    </Square> 
    </Shapes> 
    <Device> 
    <Name>peg</Name> 
    <type>X11</type> 
    </Device> 
    <Utilities> 
    <Software>QT</Software> 
    <Platform>Linux</Platform> 
    </Utilities> 
</Screen> 

XSLT Я попытался было:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
    <xsl:output indent="yes" /> 
    <xsl:template match="Shapes"> 
    <xsl:if test="not(preceding-sibling::*[local-name() = 'Shapes'])"> 

     <Shapes> 
     <xsl:apply-templates select="node() | @*" /> 
     <xsl:apply-templates select="following-sibling::*[local-name() = 'Shapes']" /> 
     </Shapes> 
    </xsl:if> 
    <xsl:if test="preceding-sibling::*[local-name() = 'Shapes']"> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:if> 
    </xsl:template> 
    <xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Но выход я получил (:()

<Screen> 
<Shapes> 
    <Triangle id="tri1"> 
     <color>red</color> 
     <size>large</size> 
    </Triangle> 

    <Rectangle id="rec1"> 
     <color>blue</color> 
     <size>medium</size> 
    </Rectangle> 

    <Circle id="cir1"> 
     <color>green</color> 
     <size>small</size> 
    </Circle> 

    <Square id="sqr1"> 
     <color>yellow</color> 
     <size>large</size> 
    </Square> 
    </Shapes> 

    <Rectangle id="rec1"> 
     <color>blue</color> 
     <size>medium</size> 
    </Rectangle> 
    <Circle id="cir1"> 
     <color>green</color> 
     <size>small</size> 
    </Circle> 
    <Square id="sqr1"> 
     <color>yellow</color> 
     <size>large</size> 
    </Square> 

    <Device> 
    <Name>peg</Name> 
    <type>X11</type> 
    </Device> 
    <Utilities> 
    <Software>QT</Software> 
    <Platform>Linux</Platform> 
    </Utilities> 
</Screen> 

Есть простой XSLT-код можно использовать , или есть ли какие-либо изменения в моем xslt, который я могу применить для получения результата?

ответ

7

Это должно сделать работу:

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

    <xsl:output method="xml" indent="yes"/> 

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

    <xsl:template match="/*"> 
    <xsl:copy> 
     <Shapes> 
     <xsl:copy-of select="Shapes/*"/> 
     </Shapes> 
     <xsl:apply-templates select="*[name()!='Shapes']"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Идея заключается в том, чтобы обработать все вложенные элементы Shapes отдельно на одном дыхании, а затем скопировать все остальное.

+0

Wow ... Ответ настолько упрощен и изящен, как любые другие потенциальные ответы, которые я видел в сети, и он отлично работает. Нет использования Ключей/рекурсивного предыдущего или следующего брачного вызова. Это было действительно полезно. Большое спасибо. (Не могу проголосовать, так как я довольно новичок в этом сайте) – Asheesh

+0

Спасибо, рад, что вам понравилось – MiMo

+0

Я попытался сделать то же самое, но он скопировал все, начиная от источника до выхода –

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