2010-11-04 27 views
1

Entréevaleurs de texte Stockage dans la variable des noeuds précédents

<?xml version="1.0" encoding="UTF-8"?> 
<XML> 
    <Concept> 
     <Heading-1>This is First Heading</Heading-1> 
    </Concept> 
    <Concept> 
     <Heading-2>This is Second Heading</Heading-2> 
    </Concept> 
    <Concept> 
     <Heading-2>This is First Heading</Heading-2> 
    </Concept> 
</XML> 

sortie doit être

<?xml version="1.0" encoding="UTF-8"?> 
<name>This_is_First_Heading</name> 
<name>This_is_Second_Heading</name> 
<name>1_This_is_First_Heading</name> 

Stylesheet

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" version="2.0"> 
    <xsl:template match="Concept"> 
     <xsl:variable name="name" 
         select="./Heading-1/text() | ./Heading-2/text()"/> 
     <xsl:variable name="name1" 
         select="if //Cocept/Heading-1/text()=$name 
           then concat(position(), '_' $name)} 
           else $name"/> 
     <name> 
      <xsl:value-of select="replace($name, ' ', '_')"/> 
     </name> 
    </xsl:template> 
</xsl:stylesheet> 

Problème: Je dois d'imprimer toutes les valeurs de texte rubrique sous " nom "élément". Mais s'il y a une valeur de texte similaire présente pour le hading précédent, il faut ajouter le numéro de position() avant les valeurs du texte. Je dois le faire si variable seulement, si vous pouvez voir dans Variable name1 j'essaie de mettre une logique qui va comparer la valeur du cap précédent et si trouver le texte similaire, puis mettre le numéro de position, mais en quelque sorte ne suis pas en mesure de atteindre cela. Pouvez-vous s'il vous plaît m'aider à écrire la même logique dans le nom de variable1. Merci d'avance pour votre aide.

__ _ ___Edité_ __ _ __ _ __

<xsl:template match="Concept"> 
    <xsl:variable name="name" 
        select="if (./Heading-1[1] | 
           ./Heading-2[1] | 
           ./Heading-3[1] | 
           ./Heading-4[1] | 
           ./Heading-5[1]) 
          then normalize-space((Heading-1[1] | 
               Heading-2[1] | 
               Heading-3[1] | 
               Heading-4[1] | 
               Heading-5[1]) 
               /text()[position()=last()]) 
          else normalize-space(./Heading-2[1]/text()[2])"/> 
     <xsl:variable name="name1" 
         select="if (//Concept/Heading-3/text() 
            [position()=last()] = $name) 
           then concat(position(), '_', $name) 
           else $name"></xsl:variable> 
     <xsl:variable name="name2" 
         select="if (string-length($name5)=0) 
           then concat(position(), '_', $name5) 
           else $name5"/> 
     <xsl:result-document href="XML/{replace($name2, ' ', '_')}.xml" 
          format="testing" validation="strip"> 
+0

Pouvez-vous publier l'entrée et la feuille de style en XML s'il vous plaît? Ensuite, expliquez si vous souhaitez transformer l'entrée XML en XML ou HTML, en XHTML ou en texte brut. –

+0

Votre édition n'a aucun sens pour moi ... –

+0

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

Répondre

0

L'une des solutions les plus simples XSLT possibles 2.0:

<xsl:stylesheet version="2.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="/*/*/*"> 
    <name> 
    <xsl:sequence select= 
    "concat(for $cnt in count(../preceding-sibling::*/*[. eq current()]) 
       return 
       if($cnt gt 0) 
        then concat($cnt, '_') 
        else(), 
       . 
      ) 
    "/> 
    </name> 
</xsl:template> 
</xsl:stylesheet> 

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

<XML> 
    <Concept> 
     <Heading-1>This is First Heading</Heading-1> 
    </Concept> 
    <Concept> 
     <Heading-2>This is Second Heading</Heading-2> 
    </Concept> 
    <Concept> 
     <Heading-2>This is First Heading</Heading-2> 
    </Concept> 
</XML> 

produit le résultat souhaité, correct:

<name>This is First Heading</name> 
<name>This is Second Heading</name> 
<name>1_This is First Heading</name> 

Si vous avez besoin que chacun des nœuds de texte produits dans le résultat soit réellement dans les variables, il suffit de remplacer dans le code <xsl:sequence> ci-dessus par <xsl:variable>.

+0

Merci Dimitre !! Cela résout mon problème. – Pankaj

0

Voici une feuille de style de l'échantillon qui produit le résultat que vous avez demandé:

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

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

    <xsl:key name="k1" match="Concept/*" use="."/> 

    <xsl:template match="Concept/*"> 
    <xsl:variable name="preceding" select="key('k1', .)[. &lt;&lt; current()]"/> 
    <name> 
     <xsl:choose> 
     <xsl:when test="$preceding"> 
      <xsl:value-of select="concat(count($preceding), '_', replace(., ' ', '_'))"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="replace(., ' ', '_')"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </name> 
    </xsl:template> 

</xsl:stylesheet> 
+0

+1 Bonne réponse. Mais j'utiliserais 'concat (concat (count ($ precedant), '_') [$ precedent], remplace (., '', '_'))' Pour le rendre moins verbeux. –

+0

Merci pour la réponse. J'ai besoin de votre aide pour implémenter cette solution dans mon scénario actuel. Je crée des fichiers xml en fonction de ces noms. Et maintenant mon nœud de contexte est "Concept" et non "Concept/*". Pouvez-vous m'aider à faire la même chose dans la feuille de style ci-dessous: – Pankaj

+0

J'ai mis à jour ma question avec le tag édité. J'ai besoin d'utiliser cette logique dans "xsl: result-document" pour éviter le nom de fichier. Merci encore pour votre aide. – Pankaj