2010-03-12 6 views
3

j'ai le modèle XSL (I omis le modèle pour l'organisation, laissez-moi savoir si cela est nécessaire):sortie générant de transformation XSL à partir d'autres nœuds

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">  
<xsl:output method="html" indent="yes" omit-xml-declaration="yes"/> 

<xsl:template match="SOAP-ENV:Body/*[local-name()='Publisher']"> 
    <html>  
     <xsl:call-template name="body" /> 
    </html>  
</xsl:template> 
    <xsl:template name="body"> 
    <BODY> 
     <br/> 
     <center> 
      <font face="arial" size="2"> 
       <b>Publisher <xsl:value-of select="*[local-name()='Organization']/*[local-name()='PublisherData']/*[local-name()='PublisherName']"/> 
       </b> 
      </font> 
     </center> 
     <br/> 
     <xsl:apply-templates select="*[local-name()='Organization']"/> 
    </BODY> 
</xsl:template> 
</xsl:stylesheet> 

Le modèle précédent génère la sortie que je veux, il est la génération les balises contenant la sortie générée par le template "body". Le problème que j'ai est que, avant la balise d'ouverture, je reçois du texte en sortie d'un nœud précédent. Je ne sais pas pourquoi cela se passe puisque je ne sélectionne pas ces autres nœuds. Par exemple:

<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
     xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
     <SOAP-ENV:Header> 
      <n1>abc</n1> 
       <n2>def</n2> 
     </SOAP-ENV:Header> 
     <SOAP-ENV:Body> 
      <Publisher> 
          <!--Child nodes here --> 
        </Publisher> 
      </SOAP-ENV:Body> 
    </SOAP-ENV:Envelope> 

Compte tenu du fragment précédent exemple XML, ma sortie contiendrait ce que j'attendre de mise en forme l'élément Publisher, mais je suis aussi obtenir les nœuds texte des enfants du SOAP-ENV: En-tête nœud.

Je veux seulement transformer le contenu de l'élément de l'éditeur, mais dans la sortie, je vais:

abc 
def 
//Expected output transforming Publisher goes here 

Ma question est, pourquoi abc et sont sélectionnés def?

+1

Vous devrez publier l'intégralité du XSL pour que nous puissions savoir d'où provient l'autre texte. Aussi, postez un échantillon de XML assez grand pour reproduire le problème (et pas plus grand!). Enfin, publiez le XML résultant. –

+0

@Abel: Je vous recommande de vous débarrasser de tous les trucs '* [local-name() = ...]'. Il blote votre XSL et ne sert à rien. '' est beaucoup plus agréable, n'est-ce pas? – Tomalak

+0

@Tomalak: vous avez raison vu l'exemple précédent, j'ai simplement supprimé les espaces de noms et les préfixes (j'en ai un tas) pour plus de clarté. –

Répondre

3

La sortie est générée en raison des built in template rules lesquels:

  • copie nœuds de texte sur la sortie
  • appliquer des modèles à éléments

La section pertinente de la recommandation XSLT 1.0 est inclus ci-dessous .

Vous pouvez simplement vouloir un modèle de ne rien faire pour l'en-tête SOAP-ENV:.

<xsl:template match="SOAP-ENV:Header"> 
</xsl:template> 

Certains des éléments de votre document source ne se trouvent pas dans un espace de noms. Dans une expression XPath, les éléments qui n'ont pas d'espace de noms peuvent être référencés par leur nom local littéral. Vous n'avez besoin d'utiliser local-name() que si vous ne connaissez pas l'espace de noms d'un élément.

Voici une version modifiée de votre feuille de style. Il commence par un modèle correspondant à /, puis sélectionne explicitement les nœuds que nous voulons.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 

    <xsl:output method="html" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:template match="/"> 
     <html>  
      <xsl:apply-templates select="SOAP-ENV:Body/Publisher" /> 
     </html>  
    </xsl:template> 

    <xsl:template name="Publisher"> 
     <body> 
      <br/> 
      <center> 
       <font face="arial" size="2"> 
        <b> 
         <xsl:text>Publisher </xsl:text> 
         <xsl:value-of select="Organization/PublisherData/PublisherName"/> 
        </b> 
       </font> 
      </center> 
      <br/> 
      <xsl:apply-templates select="Organization"/> 
     </body> 
    </xsl:template> 
</xsl:stylesheet> 

règles modèle intégré-

Il est intégré dans la règle de modèle pour permettre le traitement récursif de continuer en l'absence d'un modèle réussi correspondance par une règle de modèle explicite dans la feuille de style. Cette règle de modèle s'applique aux nœuds d'élément et au nœud racine .Ce qui suit montre la règle équivalent du modèle incorporé :

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

Il y a aussi une règle de modèle intégré pour chaque mode, ce qui permet un traitement récursif de continuer dans le même mode dans le absence de correspondance réussie avec un modèle explicite règle dans la feuille de style. Cette règle de modèle s'applique aux deux nœuds d'élément et au nœud racine. L'illustration suivante montre l'équivalent de la règle du modèle intégré pour le mode m.

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

Il y a aussi une règle de modèle intégré pour le texte et les noeuds d'attribut qui copie le texte:

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

Le haut-règle de modèle pour instructions de traitement et commentaires est-à- ne fais rien.

<xsl:template match="processing-instruction()|comment()"/> 

La règle de modèle intégré pour nœuds d'espace de noms est aussi de ne rien faire. Aucun motif ne peut correspondre à un nœud d'espace de noms ; Par conséquent, la règle de modèle intégrée est la seule règle de modèle appliquée aux noeuds de l'espace de noms .

Les règles de modèle intégrées sont traitées comme si elles étaient importées implicitement avant que la feuille de style et ont donc plus faible priorité des importations que toutes les autres règles de modèle. Ainsi, l'auteur peut remplacer une règle de modèle intégrée en incluant une règle de modèle explicite .

+0

@Lachlan: Je vous suggère de lui dire pourquoi son XSL n'a pas fonctionné, pas juste lui montrer comment le faire fonctionner. –

+0

Super! Cela a fonctionné, mais je ne comprends pas, pourquoi utiliser un modèle de rien pour SOAP-ENV: Header a résolu le problème? Merci! –

+0

J'ai compris, merci! –

Questions connexes