excuses pour la nature de base de ces questions - je suis tout neuf à XSLT (et à empiler trop de débordement).
Je dois transformer le XML suivant étant renvoyé par un service Web SharePoint: P> < Pré> xxx pré>
dans ceci: p> essentiellement, je dois supprimer tous les attributs de chaque élément de groupe sauf le nom. Après beaucoup de recherches et de bricolage, et de déposer notamment la déclaration d'espace de nom de l'original XML, j'ai proposé quelque chose qui me donne presque exactement ce dont j'ai besoin: p> Cependant, au lieu d'un attribut de nom, ce qui précède me donne la valeur de l'attribut de nom inséré sous forme de texte dans l'élément de groupe, comme: p> Ce sera finalement consommé par une application tierce qui s'attend à ce que l'Attribut-Centric XML. Je suis sûr que je manque quelque chose d'embarrassant évident, mais peu importe ce que je fais avec cela, je ne peux pas sembler tirer simplement l'attribut de nom. Deux questions: p> Comment puis-je modifier le XSLT pour renvoyer un attribut de nom pour chaque élément de groupe, au lieu de sa valeur sous forme de texte? P> et, comment gérer correctement l'espace de noms? Lorsque je l'ai inclus dans le XSLT, essayez plusieurs méthodes basées sur des exemples que j'ai trouvés ici et ailleurs sur le Web, je ne reçois rien du tout. p> Merci d'avance pour tout conseil. p> p>
4 Réponses :
Je pense qu'il devient plus facile pour vous si vous n'utilisez pas réponse à la deuxième question est un FAQ . Déclarez l'espace de noms et utilisez le préfixe déclaré dans votre XSL. Solution finale: P> xsl: copier code> ici. Essayez ceci:
<xsl:stylesheet version="1.0"
xmlns:myns="http://schemas.microsoft.com/sharepoint/soap/director/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/myns:GetGroupCollectionFromUser">
<Groups>
<xsl:apply-templates select="myns:Groups" />
</Groups>
</xsl:template>
<xsl:template match="myns:Groups/*">
<xsl:element name="Group">
<xsl:attribute name="Name">
<xsl:value-of select="@Name" />
</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Cela ne renvoie que le dernier groupe pour moi, bien que j'avoue que je ne connais pas trop xslt, il me manque peut-être quelque chose. Je passe testant en utilisant xslt.online-toolz.com/tools/xslt-transformation .php
Ops, je me blâme ... Maintenant, vous avez la solution la plus simple.
@empo - Votre premier modèle ne correspond à aucun élément du document source en raison de ne pas respecter les espaces de noms. Votre exemple de feuille de style complet ne produit pas la sortie demandée.
@Iwburk: Je donnais juste des allusions, ce n'est pas si gentil et ambigu, vrai. Vous avez la solution complète maintenant.
Ceci est inutilement long et convolué. En outre, incorrect, car il perd l'espace de noms par défaut.
@Dimitre: J'aime votre expression Convoluted i>. Désolé de ne pas être le maître de XSLT B>.
Cela semble fonctionner pour moi:
Complètement incorrect: Notez l'espace de noms par défaut. En outre, la sortie perd l'élément supérieur.
@Dimitre - Ce n'est pas une solution entière - elle est basée sur la solution de l'OP, remplaçant uniquement le modèle de groupe.
Ce modèle ne correspond à aucun noeud - en raison de l'espace de noms par défaut. Aucun moyen, cela pourrait produire un résultat non vide. Vous n'avez même pas testé et vérifié que votre solution proposée produit réellement le résultat recherché.
@Dimitre - c'est injuste. En fait, je l'ai testé. Cela fonctionne sans l'espace de noms (car l'OP a dit ses œuvres "après avoir [...] abandonner la déclaration d'espace de noms à partir du XML d'origine"), bien que cela ne soit pas optimal.
L'OP a dit qu'il ne pouvait pas faire fonctionner sa transformation dans le cas de l'espace de noms par défaut - et non qu'il souhaitait une solution sans espace de noms.
Le moyen de gérer ces situations consiste à remplacer la transformation de l'identité: sortie: p> Notez que la sortie est correctement NomsPaçonné. P> Cette solution est préférée en raison de sa simplicité et de sa flexibilité. Tous les nœuds et attributs sont copiés comme, à moins d'une substitution qui spécifie un comportement alternatif. P> p>
+1 Il a l'air très puissant (ésotérique à moi), mais en l'essayant d'essayer de copie tous les attributs de la sortie. Où msft code> vient de?
La source XML spécifie un espace de noms: xmlns = "http://schemas.microsoft.com/sharepoint/soap/director y /" code>. Cela doit être représenté dans le XSLT. Voir l'élément stylesheet code> pour l'attribution d'un nom - dans ce cas msft code> - à l'espace de noms trouvé dans la source de la source, de sorte que vous puissiez désigner correctement l'élément. plus tard.
OK, mais dans votre solution, tous les attributs sont toujours copiés à la sortie.
@empo - non, ils ne sont pas. Utilisez-vous l'entrée EXACT i> INPUT et MY exacte i> la feuille de style? Je suppose que vous ne comptaez pas les espaces de noms.
@empo - Notez que j'ai décidé de mettre à jour pour utiliser xsl: copier code>, mais de chaque façon, cela ne produit pas tous les attributs.
@lwburk: Vous pouvez être intéressé de voir une solution plus courte que la vôtre qui est complètement push-style.
Merci Lwburk - Cela a travaillé pour moi dans mon outil de test - mon application tiers ne l'interpréte pas correctement, mais je n'ai aucun moyen de savoir ce qu'il utilise comme moteur XSLT. Devait aller avec l'exemple de Dimitire finalement, mais le vôtre aidé aussi, très apprécié.
@Dimitre - Votre solution est plus courte, mais moins résiliente à changer. Et si quelqu'un vient et ajoute un nouvel élément sous la racine avec un attribut code> nom cod> ajoute un nom code> nom code> à l'élément code> code> " Il serait enlevé. Bien sûr, seul l'OP peut dire si c'est le résultat attendu, mais je pense que beaucoup le trouveraient inattendus. Il existe une tension entre la solution qui ne fait que les changements localisés, et une solution plus courte généralisée.
@lwburk: l'étape suivante pour faire une solution plus résiliente à changer consiste à prendre en compte la météo ... :) Plus sérieusement, vous avez raison que nous ne connaissons pas le contexte de l'OP, c'est pourquoi répondre à la question strictement est plus raisonnable.
@LWBURK: Non, si un attribut nom code> est ajouté n'importe où, il sera copié i> sera copié.
@Dimitre - Oups. J'ai dit ça en arrière. Bien sûr, je voulais dire que serait copié i> serait copié, mais d'autres seraient enlevés. Je ne me sens pas vraiment fortement à ce sujet, de toute façon. Chaque réponse produit la même sortie pour cette entrée exacte i>, mais a un comportement différent pour une entrée modifiée. Je ne peux pas prédire l'avenir, mais parfois c'est amusant d'essayer :)
@Dimitre - Un exemple courant de prévision de l'avenir offre la transformation de l'identité correcte lorsque quelqu'un demande comment copier un document qui ne contient aucun attribut ou des instructions de traitement ou autre. Vous auriez pour que vous puissiez simplement fournir un modèle qui ne copie que des éléments et il serait i> produirait leur sortie désirée sur ce document i>. Mais il est raisonnable de deviner que les attributs pourraient être ajoutés plus tard et qu'ils seraient probablement surpris quand ils ne copétaient pas.
Ceci est peut-être l'une des transformations les plus courtes qui produit correctement le résultat recherché strong>: lorsqu'il est appliqué sur le document XML fourni fort> : p> Le résultat correct est produit strong>: p> la règle d'identité (modèle) copie chaque nœud "tel quel". strong> p> li>
Il n'y a qu'un seul modèle qui remplace la règle d'identité forte>. Il correspond à n'importe quel attribut dont le nom n'est pas "NOM". Le corps du modèle est vide et il en résulte tout attribut correspondant non copié. P> li>
ol> Utiliser et remplacer la règle d'identité est le modèle de conception XSLT le plus fondamental et le plus puissant. Lisez-y à propos de ici strong>. P> p>
Merci beaucoup! Et pour la référence d'identité, cela va être utile. Suis-je correct en supposant que le nœud () | @ * renvoie tous les nœuds plus tous les attributs? Et j'ai lu @ * [pas (nom (nom () = 'nom')] comme "Obtenir tous les attributs de ne pas avoir le nom du nom", pourtant, cela fait le contraire? Encore une fois, excuses pour les questions de base.
@RLG: nœud () | @ * code> est une expression XPath (dans ce cas un motif de correspondance). Il sélectionne i> tout enfant :: nœud (nœud (nœud () code> ou n'importe quel attribut :: * code> du nœud actuel. Cela signifie: Tous les attributs et tous les éléments, les nœuds textuels, les instructions de traitement et les noeuds de commentaires - enfants.
@RLG: @ * [non (nom () = 'nom')] code> sélectionne n'importe quel attribut, dont le nom n'est pas "Nom". Cela signifie que le modèle ayant ce modèle de correspondance est sélectionné pour traiter tous ces attributs. Le traitement est null - ils ne sont donc pas copiés à la sortie.