2012-04-04 16 views
2

Ich habe die folgende XML-Eingabe:Wie komplexe XML-Elemente kombinieren XSLT mit

<root age="1"> 
<description>some text</description> 
<section> 
    <item name="a"> 
     <uuid>1</uuid> 
    <item> 
</section> 
<section> 
    <item name="b"> 
     <uuid>2</uuid> 
    <item> 
</section> 
</root> 

Ich mag würde es in die folgenden XML verwandeln:

<root age="1"> 
<description>some text</description> 
<section> 
    <item name="a"> 
     <uuid>1</uuid> 
    <item> 
    <item name="b"> 
     <uuid>2</uuid> 
    <item> 
</section> 
</root> 

Vielen Dank im Voraus.

+0

was die Regel, es zu verwandeln ist? Alle Kinder aller Sektionen in einen Abschnitt einfügen? – hroptatyr

+0

@hroptatyr Sie haben Recht. Setzen Sie alle Kinder aller Sektionen in einen Abschnitt –

+1

Duplizieren? http://stackoverflow.com/questions/10007021/how-to-combine-xml-elements-using-xslt – ceving

Antwort

1

Eine einfachere und kürzere Lösung:

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

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

<xsl:template match="section[1]"> 
    <section> 
    <xsl:apply-templates select="../section/node()"/> 
    </section> 
</xsl:template> 

<xsl:template match="section[position() > 1]"/> 
</xsl:stylesheet> 

Wenn diese Transformation auf der mitgelieferten XML-Dokument angewendet wird:

<root age="1"> 
    <description>some text</description> 
    <section> 
     <item name="a"> 
      <uuid>1</uuid> 
     </item> 
    </section> 
    <section> 
     <item name="b"> 
      <uuid>2</uuid> 
     </item> 
    </section> 
</root> 

das will, ist korrektes Ergebnis produziert:

<root age="1"> 
    <description>some text</description> 
    <section> 
     <item name="a"> 
     <uuid>1</uuid> 
     </item> 
     <item name="b"> 
     <uuid>2</uuid> 
     </item> 
    </section> 
</root> 
+0

Dank @Dimitre Novatchev funktioniert es. Das ist eine wirklich elegante Lösung. Könnten Sie bitte eine kurze Erklärung zu Abschnitt [1] und Abschnitt [Position()> 1] geben –

+0

@SashaKorman: 'Abschnitt [1]' ist ein Match-Muster für den ersten Abschnitt (des übergeordneten). Das heißt, wir wollen ein 'section' Element nur einmal verarbeiten und erzeugen. 'section [position()> 1]' ist ein weiteres Übereinstimmungsmuster, das mit allen "section" -Elementen übereinstimmt, außer dem, was mit dem vorherigen Übereinstimmungsmuster übereinstimmt. Die passende Vorlage hat keinen Körper, daher werden diese 'section' Elemente überhaupt nicht verarbeitet. –

+0

danke für die Klarstellung –

1

Hier ist mein xslt-1.0 Versuch:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

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

    <xsl:template match="*"> 
    <xsl:copy> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:copy> 
    </xsl:template> 

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

    <xsl:template match="section"> 
    <xsl:apply-templates select="*"/> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Danke @hropatyr funktioniert es –