12
votes

Utilisation de XSL pour remplacer les nœuds XML avec de nouveaux nœuds

J'ai besoin d'une solution XSL pour remplacer les nœuds XML avec de nouveaux nœuds.

Dites que j'ai la structure XML existante suivante: xxx

et je veux remplacer celui-ci. noeud de critère avec: xxx

de sorte que le résultat XML final est le suivant: xxx

J'ai essayé d'utiliser la sous-chaîne-avant et Substring-Après simplement copier la première moitié de la structure, copiez simplement la seconde moitié (afin de remplir mes nouveaux nœuds entre les deux moitiés), mais il semble que les fonctions de sous-chaîne ne reconnaissent que le texte entre les balises des nœuds , et pas les tags eux-mêmes comme je le souhaite. :(: (

Toute autre solution?


1 commentaires

Bonne question (+1). Voir ma réponse pour une solution correcte et courte. Notez que la solution actuellement acceptée a une faille logique (il arrive simplement de fonctionner avec votre document XML, mais produira généralement des résultats erronés avec d'autres documents XML).


3 Réponses :


28
votes

XSL ne peut pas remplacer em> rien. Le mieux que vous puissiez faire est de copier les pièces que vous souhaitez conserver, puis de produire les pièces que vous souhaitez modifier au lieu des pièces que vous ne voulez pas conserver.


Exemple: P>

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

    <!-- This is an identity template - it copies everything
         that doesn't match another template -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

  <!-- This is the "other template". It says to use your BBB-DDD elements
       instead of the AAA element -->
  <xsl:template match="criterion[.='AAA']">
    <xsl:element name="criterion">
      <xsl:text>BBB</xsl:text>
    </xsl:element>
    <xsl:element name="criterion">
      <xsl:text>CCC</xsl:text>
    </xsl:element>
    <xsl:element name="criterion">
      <xsl:text>DDD</xsl:text>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>


15 commentaires

@heartGreek Faites un regard très étroit sur les modèles John a mis en place. Les modèles correspondant aux éléments XML sont la clé pour utiliser efficacement XSLT.


Merci d'avoir fourni un exemple de code .. C'est exactement ce que j'essayais de réaliser !! Bien que cette solution fonctionne pour moi, je veux vraiment le comprendre aussi. J'ai fait des choses similaires avec le deuxième modèle (match = "critère ['AAA']") mais la partie clé que je ne connaissais pas (ni ne réalisez) était le modèle qui copié tout ce qui ne correspond pas à un autre modèle. Ainsi ... Pouvez-vous expliquer comment le match XPath = "@ * | noeud ()" atteint cela? Je suis nouveau à Xpath et XSL, donc je ne connais toujours pas les instantanmes.


Merci! Cela rend beaucoup plus de sens maintenant que je connais des modèles ont des priorités! :RÉ


@Downvoter: Si vous avez quelque chose à dire, veuillez le dire avec des mots. "-1" n'est pas très éloquent.


+1 @john Saunders - Je suppose que vous avez un bulletail down parce que le match de modèle était incorrect. Il avait la valeur de chaîne littérale 'AAA' comme filtre de prédicat, qui évalue vers true () et garantit donc que tous les éléments Critère sont assortis. Vous avez eu la bonne idée et une bonne explication avec l'exemple. J'espère que cela ne vous dérange pas que j'ai corrigé le filtre de prédicat dans les critères @Match pour vous.


@Mads: Merci beaucoup. Le fait qu'il évalue comme vrai () explique comment il semblait fonctionner quand je l'ai essayé. Je souhaite seulement que le Downvoter ait expliqué aussi bien que vous l'avez fait; Il aurait été possible de corriger le problème immédiatement.


J'ai retourné mon bowvote, une fois que cette réponse a été corrigée. Merci à @ Mads-Hansen!


Pourquoi utilisez-vous pour produire ... des éléments littéraux-éléments ?


Une autre observation: la ligne 3 de votre feuille de style est complètement inutile - mieux supprimée: `xmlns: msxsl =" urn: schemas-microsoft-com: xslt "exclude-résultat-préfixes =" msxsl "`


@Dimitre: J'essayais de répondre à la question, de ne pas créer un livre sur les meilleures pratiques de XSLT. Merci d'avoir souligné ce problème trivial causé par le Template par défaut pour un document XSLT dans Visual Studión 2008.


Alors, pourquoi utilisez-vous pour produire ... littéral-éléments-éléments ? Est-ce aussi un "problème trivial"?


Merci à tous pour vos contributions. En fait, j'ai fini par utiliser Parce que je ne veux pas que je ne veux pas, la valeur à l'intérieur du nœud (la valeur peut changer).


@Dimitre: donner une réponse rapide qui illustre le point que XSL ne peut rien remplacer. Également illustrer rapidement l'utilisation d'une transformation d'identité. Encore une fois, je n'essayais pas de créer une feuille de style de la meilleure pratique, et je n'ai pas été intéressé à attendre votre contribution. N'hésitez pas à poster une meilleure réponse et laissez la meilleure réponse à gagner. Oh, attendez. Vous avez fait poster une meilleure réponse. Désolé j'ai oublié.


Ce n'est pas correct du tout: "Pour donner une réponse rapide qui illustre le point que XSL ne peut rien remplacer." ! En ce qui concerne la réponse "gagnante", soyez fier d'être imparfait et réparé et toujours très loin d'une réponse parfaite peut "gagner". C'est ce que je me batte contre - et assurez-vous que je vais descendre toute réponse incorrecte future! Ainsi, les futures "contributions" comme celle-ci sont attendues avec impatience. :)


@Dimitre: Excellent. Et j'espère que vous n'aurez pas besoin d'être invité à expliquer vos bowvotes. Vous avez aidé les lecteurs une bonne affaire en expliquant celui-ci.



0
votes

Sous la règle générale de plus à un ivrail-one-way-a-cat xxx


2 commentaires

Pourriez-vous élaborer comment cela est différent de ma solution?


@John: Aucune différence, le vôtre a beaucoup plus d'explications sur cependant. Je pense que j'avais posté l'avoir posté et / / / / / Mise à jour ... tu me battes au coup de poing :-)



9
votes

Voici une solution correcte, qui est probablement l'une des plus courtes : xxx

lorsque cette transformation est appliquée sur le document XML fourni, le Le résultat recherché est produit : xxx

note :

  1. L'utilisation du modèle d'identité .

  2. Comment le modèle d'identité est remplacé par un modèle spécifique - uniquement pour un élément critère , dont la valeur de chaîne est 'AAA' . .


6 commentaires

"assez inexact"? Je crois que vous avez signalé une seule erreur, que Mads Hansen a non seulement signalé, mais également expliquée et corrigée.


@ John-Saunders: Je suis heureux que l'erreur soit corrigée. Va essayer d'annuler mon bowvote. J'espère que cela vous aidera ensuite à payer plus d'attention. Mon principe est de savoir tout ce qui contient des erreurs (au moins évidentes). Malheureusement, je ne peux pas me permettre le temps de corriger les erreurs dans les réponses des autres.


@Dimitre: votre attitude n'est pas utile. J'ai tenté de répondre à la question. J'ai fait une erreur. Le test de mon code non corrigé évalue à true () . En conséquence, la feuille de style semblait fonctionner. Il n'y a aucune raison de votre commentaire "payer plus d'attention". Si vous ne pouvez pas être dérangé pour participer à la communauté ici (que fait implique d'aider à corriger les mauvaises réponses), vous pourriez alors envisager une différence différente, où votre contribution inutile d'un bowvote silencieux ira intégré.


@ John-Saunders: Je suis vraiment "dérangé" de participer à la communauté - surtout quand je vois une réponse incorrecte suspendue pendant des heures et être copiée par des personnes qui ne soupçonnent pas qu'il y a une faille dedans. En ce qui concerne l'édition d'une réponse comme celle-ci - Non, pour le modifier, cela signifie-t-il de la réécrire complètement - je l'ai fait en postant ma réponse. John, il y a tant de problèmes "mineurs" dans votre réponse que je n'ai vraiment pas le temps.


@Dimitre: Mads Hansen avait le temps - il a dû modifier une ligne pour empêcher les personnes copiant une erreur importante. Plus de choses n'était pas nécessaire. Même si vous aviez ajouté un commentaire lorsque vous avez évité, indiquez qu'il y avait une erreur alors ne copiez pas le code, cela aurait sauvé les lecteurs la tragédie de copier mon code.


@ John-Saunders: Votre code avait / a un certain nombre de problèmes et j'aurais besoin de plus de temps pour les commenter que d'écrire et de poster une réponse correcte. S'il vous plaît, ne pas distraire des problèmes de votre code. Pourquoi utilisez-vous pour produire éléments littéraux-résultat ? J'ai demandé cela hier et vous n'avez pas corrigé cela dans votre réponse!