2010-11-18 4 views
3

J'ai le code XML suivantXSLT divisé au nœud enfant

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

que je veux transformer en

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

En d'autres termes: Je voudrais diviser l'élément para à la position où l'élément de lien est. Y a-t-il des indices?

+0

Bonne question, +1. Voir ma réponse pour une solution complète et très courte/simple. :) –

Répondre

0

Cette feuille de style:

<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> 

Sortie:

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

Remarque: traversal à grain fin.

Modifier: Code Compact:

<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

Le noeud 'para' devrait-il être copié au lieu d'être généré? Et si il a des attributs? Bruno

2

Cette 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> 

lorsqu'il est appliqué sur le document XML fourni:

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

produit le résultat souhaité, correct:

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

Prenez note:

  1. L'utilisation de la règle d'identité à copier chaque nœud en l'état.

  2. La Primauté identité avec des modèles pour traiter uniquement des nœuds spécifiques

  3. La simplicité et la puissance qui découlent de l'utilisation 1. et 2. ci-dessus.

+0

Salut Dimitre, merci pour votre solution très élégante, mais j'ai le problème que le modèle de contenu de permette aussi d'autres éléments, ce qui ne devrait pas finir le paragraphe comme devrait le faire le lien. Donc j'ai dû utiliser la suggestion d'Alejandros. – Roman

+0

@Roman: Vous pouvez éditer votre question et montrer la structure réelle de votre XML, puis je vais modifier ma réponse pour qu'elle corresponde à la structure XML que je n'ai pas encore vue. Personne ici n'est clairvoyant. :) –

Questions connexes