2010-11-18 14 views
3

Ich habe die folgende XML-CodeXSLT aufgeteilt in untergeordneten Knoten

<para>Lorem ipsum <link>dolor</link> sit amet</para> 

, die ich

<para>Lorem ipsum </para><link>dolor</link><para> sit amet</para> 

Mit anderen Worten umwandeln wollen: Ich möchte das para-Element an der Position spalten wo Linkelement ist. Gibt es Hinweise?

+0

Gute Frage, +1. Siehe meine Antwort für eine vollständige und sehr kurze/einfache Lösung. :) –

Antwort

0

Dieses Sheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[1]"/> 
     </xsl:copy> 
     <xsl:apply-templates select="following-sibling::node()[1]"/> 
    </xsl:template> 
    <xsl:template match="para"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[1]"/> 
     </xsl:copy> 
     <xsl:apply-templates select="link" mode="copy"/> 
     <xsl:apply-templates select="following-sibling::node()[1]"/> 
    </xsl:template> 
    <xsl:template match="para/link"/> 
    <xsl:template match="para/link" mode="copy"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[1]"/> 
     </xsl:copy> 
     <para> 
      <xsl:apply-templates select="following-sibling::node()[1]"/> 
     </para> 
    </xsl:template> 
</xsl:stylesheet> 

Ausgang:

<para>Lorem ipsum </para><link>dolor</link><para> sit amet</para> 

Hinweis: Feinkörnige Traversal.

bearbeiten: Compact Code:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="node()|@*" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[1]"/> 
     </xsl:copy> 
     <xsl:apply-templates select="self::para/link" mode="copy"/> 
     <xsl:apply-templates select="following-sibling::node()[1]"/> 
    </xsl:template> 
    <xsl:template match="para/link"/> 
    <xsl:template match="para/link" mode="copy"> 
     <xsl:call-template name="identity"/> 
    </xsl:template> 
    <xsl:template match="node()[preceding-sibling::node()[1] 
            /self::link/parent::para]"> 
     <para> 
      <xsl:call-template name="identity"/> 
     </para> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Soll der Knoten 'para' kopiert anstatt generiert werden? Was ist, wenn es Attribute hat? Bruno

2

Diese Transformation:

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

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

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

<xsl:template match="para/text()"> 
    <para><xsl:copy-of select="."/></para> 
</xsl:template> 
</xsl:stylesheet> 

wenn auf der mitgelieferten XML-Dokument angelegt:

<para>Lorem ipsum <link>dolor</link> sit amet</para> 

erzeugt die gewünschte, korrekte Ergebnis:

<para>Lorem ipsum </para><link>dolor</link><para> sit amet</para> 

beachten Sie:

  1. Die Verwendung der Identität Regel jeden Knoten zu kopieren, wie sie ist.

  2. Vorrangiges der Identität Regel mit Vorlagen für die Verarbeitung nur bestimmten Knoten

  3. Die äußerste Einfachheit und Leistung der aus der Verwendung 1. und 2. oben.

+0

Hallo Dimitre, danke für deine sehr elegante Lösung, aber ich habe das Problem, dass das Content-Modell von auch einige andere Elemente zulässt, die den Absatz nicht wie Link enden sollten. Also musste ich Alejandros Vorschlag verwenden. – Roman

+0

@Roman: Sie können Ihre Frage bearbeiten und die reale Struktur Ihres XML anzeigen, dann werde ich meine Antwort so ändern, dass sie der XML-Struktur entspricht, die ich noch nicht gesehen habe. Niemand hier ist ein Hellseher. :) –

Verwandte Themen