2010-03-24 4 views
2

J'essaie de garder mon xsl DRY et par conséquent je voulais appeler le même modèle pour 2 sections d'un document XML qui se trouve être le même type complexe (ContactDetails et AltContactDetails). Étant donné le code XML suivant:Appeler le même xsl: modèle pour différents noms de nœuds du même type complexe

<?xml version="1.0" encoding="UTF-8"?> 
<RootNode> 
    <Name>Bob</Name> 
    <ContactDetails> 
     <Address> 
      <Line1>1 High Street</Line1> 
      <Town>TownName</Town> 
      <Postcode>AB1 1CD</Postcode> 
     </Address> 
     <Email>[email protected]</Email> 
    </ContactDetails> 
    <AltContactDetails> 
     <Address> 
      <Line1>3 Market Square</Line1> 
      <Town>TownName</Town> 
      <Postcode>EF2 2GH</Postcode> 
     </Address> 
     <Email>[email protected]</Email> 
    </AltContactDetails> 
</RootNode> 

J'ai écrit une feuille de style XSL comme suit:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="/"> 
     <PersonsName> 
      <xsl:value-of select="RootNode/Name"/> 
     </PersonsName> 
     <xsl:call-template name="ContactDetails"> 
      <xsl:with-param name="data"><xsl:value-of select="RootNode/ContactDetails"/></xsl:with-param> 
      <xsl:with-param name="elementName"><xsl:value-of select="'FirstAddress'"/></xsl:with-param> 
     </xsl:call-template> 
     <xsl:call-template name="ContactDetails"> 
      <xsl:with-param name="data"><xsl:value-of select="RootNode/AltContactDetails"/></xsl:with-param> 
      <xsl:with-param name="elementName"><xsl:value-of select="'SecondAddress'"/></xsl:with-param> 
     </xsl:call-template> 
    </xsl:template> 
    <xsl:template name="ContactDetails"> 
     <xsl:param name="data"></xsl:param> 
     <xsl:param name="elementName"></xsl:param> 
     <xsl:element name="{$elementName}"> 
      <FirstLine> 
       <xsl:value-of select="$data/Address/Line1"/> 
      </FirstLine> 

      <Town> 
       <xsl:value-of select="$data/Address/Town"/> 
      </Town> 
      <PostalCode> 
       <xsl:value-of select="$data/Address/Postcode"/> 
      </PostalCode> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

Quand je tente d'exécuter la feuille de style, il est de me plaindre que je dois:

Pour utiliser un fragment d'arborescence de résultats dans une expression de chemin, utilisez exsl: node-set() ou spécifiez la version 1.1

Je ne veux pas aller à la version 1.1 .. Donc, quelqu'un sait comment faire fonctionner l'exsl: node-set() pour l'exemple ci-dessus?

Ou si quelqu'un connaît une meilleure façon d'appliquer le même modèle à 2 sections différentes, cela m'aiderait vraiment?

Merci

Dave

Répondre

8

Vous êtes en train de faire rouler ça du mauvais côté (la mauvaise extrémité étant presque toujours: essayer d'appliquer le paradigme de programmation impérative à XSLT).

C'est vraiment facile à faire par correspondance de modèle.

<xsl:template match="RootNode"> 
    <PersonsName> 
    <xsl:value-of select="Name"/> 
    </PersonsName> 
    <xsl:apply-templates select="ContactDetails|AltContactDetails" /> 
</xsl:template> 

<xsl:template match="ContactDetails|AltContactDetails"> 
    <xsl:copy> 
    <FirstLine> 
     <xsl:value-of select="Address/Line1"/> 
    </FirstLine> 
    <Town> 
     <xsl:value-of select="Address/Town"/> 
    </Town> 
    <PostalCode> 
     <xsl:value-of select="Address/Postcode"/> 
    </PostalCode> 
    </xsl:copy> 
</xsl:template> 

Lâchez l'idée que vous avez à dire au processeur XSLT quoi faire (en faisant des modèles nommés et de les appeler, « style impératif »).

Le processeur XSLT choisit ce que les modèles à appeler. En commençant à la racine (/), il vérifie de manière récursive les modèles correspondants pour chaque nœud visité. Il traverse votre XML d'entrée tout seul - votre seul travail consiste à lui fournir des modèles correspondants pour les nœuds que vous souhaitez avoir traité d'une manière spéciale.

Vous pouvez déposer un modèle personnalisé pour les nœuds qui nécessitent un traitement spécial et faire confiance à votre processeur XSLT pour l'appeler une fois qu'ils sont apparus. Tout ce que vous devez vous assurer dans vos modèles est que la traversée se poursuit en déclarant un <xsl:apply-templates /> approprié.

+0

Merci pour cela .. Je ne savais pas sur le tuyau dans le modèle de correspondance .. Cela m'a vraiment aidé. – CraftyFella

+0

@CraftyFella: Ces soi-disant «expressions de correspondance» sont un sous-ensemble de XPath, beaucoup de choses qui fonctionnent dans XPath fonctionneront ici aussi. – Tomalak

+0

Bonne réponse! +1 –

2

Pourquoi ne pas faire le modèle

<xsl:template match="ContactDetails|AltContactDetails"> 

et faire le test pour déterminer le nom de l'élément de sortie à l'intérieur du modèle à la place?

+0

Frickin Sweet .. fonctionne totalement .. Je vais écrire la réponse complète comme je devais le changer en xsl: applytemplates plutôt que d'appeler: modèle – CraftyFella

+0

Avec ' WPF - même type de menu contextuel sur différents systèmes d'exploitation

  • 9. Exécution de plusieurs instances Grails/Jetty sur le même serveur et le même port, mais avec des noms d'hôte différents
  • 10. Une méthode de modèle devrait-elle appeler 'save' elle-même?
  • 11. XSL deux boucles for-each pour le même nœud
  • 12. xsd: element même, différents attributs
  • 13. Possible d'avoir le même contrat, la même liaison, la même adresse, mais des ports différents?
  • 14. Définir une session pour différents domaines du même serveur?
  • 15. différents itinéraires, mais en utilisant le même contrôleur pour les sous-classes de modèle dans Rails
  • 16. Création de la même page de connexion pour différents utilisateurs
  • 17. Différents msi avec le même code produit
  • 18. Même .vimrc, deux ordinateurs différents
  • 19. Correspondances multiples du même type dans preg_match
  • 20. Linq2Sql: comment gérer des tables avec le même nom et différents noms de schéma
  • 21. pouvez-vous appeler un modèle dans un modèle en xsl
  • 22. Trouver des commandes du même type
  • 23. Cakephp deux paginations séparées du même modèle
  • 24. Solr DatImportHandler, plusieurs résultats du même type?
  • 25. Eclipse ne peut pas trouver de modèle xsl dans un autre fichier dans le même répertoire
  • 26. Même présentateur travaillant avec différents référentiels
  • 27. GWT: utilise le même modèle d'interface utilisateur pour plusieurs pages?
  • 28. C++: inclure plusieurs fichiers d'en-tête ayant le même nom d'espaces de noms différents
  • 29. Comment utiliser le même modèle avec Rails pour différents contrôleurs tout en restant RESTful
  • 30. Vérifier si l'objet est du même type