2010-08-08 4 views
2

Je suis bloqué en essayant de travailler dans ces contraintes, j'utilise XSLT 1.0 {sous .net}. Je voudrais pouvoir faire ce qui suit: je suis xsl: for-each'ing à travers un ensemble de noeuds de typeCopie XSLT avec modifications

<node> 
    <data> unknown unstructured xml </data> 
    <owner></owner> 
    </node> 

je voudrais être en mesure de sortie

<node> 
    <data> unknown unstructured xml </data> 
    <!--RESULT of calling an XSL template with certain parameters --> 
    </node> 

de ma recherche à ce jour je pensais que je pouvais faire quelque chose comme dans here:

<xsl:copy> 
     <xsl:apply-template name="findownerdetails"> 
      <xsl:with-param name="data" select="something" /> 
     </xsl:apply-template> 
    </xsl:copy> 

mais cela est apparemment pas valide. des suggestions comment faire fonctionner ceci ou accomplir quelque chose semblable? Je crains que je ne peux pas simplement appeler apply-templates comme le modèle que je veux dépendra de certaines données que je construis comme je-pour chaque à travers une liste d'éléments de nœud.

Tout conseil apprécié

+0

Bonne question (1). Voir ma réponse pour la solution la plus simple qui est entièrement dans l'esprit de XSLT, en exploitant le modèle de conception XSLT le plus fondamental - l'utilisation et le dépassement de la règle d'identité. –

Répondre

1
<xsl:template match="node"> 
    <node> 
    <xsl:copy-of select="data"/> 
    <!-- assuming this next bit in your question example 
    is something you are happy with --> 
    <xsl:call-template name="findownerdetails"> 
     <xsl:with-param name="data" select="something" /> 
    </xsl:call-template> 
    </node> 
</xsl:template> 
+0

Merci, j'aurais aimé y penser il y a un moment. Pour référence: Que se passerait-il si l'élément de noeud avait un certain nombre d'inconnus attirbutes je avais besoin de copier? Est-il également possible de faire un GreyCloud

+1

Vous pouvez faire qui répond à vos deux questions. Avec des cas plus compliqués, ou la possibilité d'un élément "propriétaire" d'un espace de noms différent, alors l'identité avec substitution (comme dans la réponse de Dimitre) devient plus élégante (nous pouvons étendre par Dimitre et ma réponse pour traiter des cas plus compliqués; est plus concis en dessous d'un certain niveau de complexité et Dimitre est au-dessus, ce qui rend aussi Dimitre plus général et un codeur XSLT devrait le savoir). (p.s., si ce qui précède a aidé, accepter la réponse serait bien). –

+0

merci pour l'info supplémentaire Jon, qui semble faire l'affaire. Étant donné que les paramètres de passage de poignée de doesnt réponse Dimitré et le vôtre ne, je vais accepter votre réponse - merci :) – GreyCloud

5

Ceci est un exemple classique d'un problème qui est le mieux résolu en utilisant et en remplaçant la identity rule:

<xsl:stylesheet version="1.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="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="owner"> 
    <owner-details> 
     <xsl:value-of select="."/> 
    </owner-details> 
</xsl:template> 
</xsl:stylesheet> 

Lorsque cette transformation est appliquée sur ce XML document (basé sur le document XML fourni avec les attributs ajoutés et les détails du propriétaire):

<node attr1="x" attr2="y"> 
    <data> unknown unstructured xml </data> 
    <owner> 
     <details> 
      <name>John Smith </name> 
      <profession>XSLT programmer</profession> 
     </details> 
    </owner> 
</node> 

Le résultat recherché est produit:

<node attr1="x" attr2="y"> 
    <data> unknown unstructured xml </data> 
    <owner-details>John Smith XSLT programmer</owner-details> 
</node> 

Prenez note:

  1. Les copies de modèle d'identité chaque nœud dans le document "en l'état" dans une mode récursive.

  2. Nous remplaçons seulement le modèle d'identité pour les éléments que nous voulons traiter d'une autre manière. Tout modèle, dont le modèle de correspondance est plus spécifique que celui du modèle d'identité, le remplace: le processeur XSLT choisit toujours le modèle correspondant le plus spécifique pour un nœud.

  3. En utilisant la règle et en remplaçant l'identité est la plus fondamentale, le plus puissant, le plus grand et la plus élégante modèle de conception XSLT. Il est utilisé exclusivement dans presque toutes les transformations XSLT: pour supprimer/renommer/modifier/ajouter des nœuds spécifiques et garder tous les autres nœuds intacts.

  4. L'OP a suggéré dans un commentaire que cette solution n'autorise pas le passage de paramètres. Ce n'est pas vrai. Tout modèle (y compris la règle d'identité) peut être écrit pour avoir des paramètres - lorsque cela est nécessaire. Dans ce cas particulier, il est pas nécessaire pour passer des paramètres via des modèles.

  5. Le modèle correspondant ownern'a pas besoin appeler un autre modèle - tout le propriétaire - un traitement spécifique peut être fait ici.

+0

Salut Dimitre, je vous remercie de votre solution, je l'ai vu une réponse similaire dans un autre thread mais j'ai peur que cela ne fonctionne pas puisque je ne peux pas passer de paramètres via l'appel . – GreyCloud

+0

@GreyCloud: Vous ne comprenez pas: 1. Vous * pouvez * transmettre des paramètres à travers n'importe quel modèle. Pour le problème dans votre question, ce n'est pas nécessaire. Modifiez la question de sorte qu'il est nécessaire de passer le paramètre (s) et je vais vous montrer comment. 2. Dans le template qui correspond à 'owner', vous n'avez pas besoin d'appeler un autre template et de lui passer un ou plusieurs paramrters - vous pouvez simplement traiter l'élément' owner' (et son sous-arbre) dans ce template - et ceci est ce que ma réponse suggère. –

+0

comment puis-je passer des paramètres via ""? – GreyCloud