2017-06-27 2 views
0

Je dois remplacer un élément dans le traitement de xml par un élément d'un autre xml si certains paramètres correspondent. Fondamentalement notifications.xml est xml dans lequel j'ai besoin de traiter les notifications et seulement remplacer/ajouter MsgText avec MsgText de notification-source.xml si dans notification-source.xml NotifId est égal à NotifId de la notification en cours. S'il n'y a pas de correspondance, conservez la notification inchangée.Les éléments de copie XSLT de xml par élément correspondent

notifications.xml

<?xml version="1.0" encoding="UTF-8"?> 
<Notifications> 
    <BatchId>DOCATTR.BATCHID</BatchId> 
    <Notification> 
    <NotifId>1</NotifId> 
    <Cid>DOCATTR.CID</Cid> 
    <EmailNotification> 
     <CcAddress>DOCATTR.EMAILCC</CcAddress> 
     <CcName>DOCATTR.EMAILCCNAME</CcName> 
     <BccAddress>DOCATTR.EMAILBCC</BccAddress> 
     <SenderAddress>DOCATTR.SENDERADDRESS</SenderAddress> 
     <SenderName>DOCATTR.SENDERNAME</SenderName> 
     <MsgText> 
     </MsgText> 
     <Expiration>DOCATTR.EXPIRATION</Expiration> 
     <Priority>DOCATTR.PRIORITYNC</Priority> 
    </EmailNotification> 
    </Notification> 
</Notifications> 

notifications-source.xml

<?xml version="1.0" encoding="UTF-8"?> 
<Notifications> 
    <Notification> 
     <NotifId>1</NotifId> 
     <MsgText> 
      <![CDATA[notif 1]]> 
     </MsgText> 
    </Notification> 
    <Notification> 
     <NotifId>2</NotifId> 
     <MsgText> 
      <![CDATA[notif 2]]> 
     </MsgText> 
    </Notification> 
</Notifications> 

C'est ce que je voulais, mais qu'elle copie texteMsg un autre endroit

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0"     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:strip-space elements="*"/> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" cdata-section-elements="MsgText"/> 
    <xsl:variable name="notifications" select="/"/> 
    <xsl:variable name="notifications-source" select="document('notifications-source.xml')"/> 
    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="/"> 
    <Notifications> 
     <xsl:for-each select="$notifications//Notification"> 
     <xsl:variable name="currentNotifId" select="./NotifId"/> 
     <xsl:for-each select="$notifications-source//Notification"> 
      <xsl:variable name="remoteNotifId" select="./NotifId"/> 
      <xsl:if test="$currentNotifId=$remoteNotifId"> 
      <xsl:copy> 
       <xsl:copy-of select="./MsgText"/> 
      </xsl:copy> 
      </xsl:if> 
     </xsl:for-each> 
     </xsl:for-each> 
    </Notifications> 
    </xsl:template> 
</xsl:stylesheet> 

ce serait bien pour utiliser saxon-il 9.6.0-6 pour cela, mais si non applicable il peut être plus récent.

J'ai donc changé de modèle celui-ci:

<xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="MsgText"> 
     <xsl:variable name="currentNotifId" select="../NotifId/text()"/> 
     <xsl:choose> 
      <xsl:when test="$notifications-source/Notifications/Notification/NotifId[text() = $currentNotifId]"> 
       <xsl:copy> 
        <xsl:copy-of select="$notifications-source/Notifications/Notification/NotifId[text() = $currentNotifId]/../MsgText"/> 
       </xsl:copy> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:copy> 
        <xsl:copy-of select="'test'"/> 
       </xsl:copy> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

Maintenant, je suis seulement le correspondant MSGTEXT. Mais actuellement, je reçois toujours <MsgText><![CDATA[test]]></MsgText> donc je ne sais pas utiliser correctement le test (choisir)

+0

Cette question est différente de https://stackoverflow.com/questions/44762709/xslt-copy-element-from-one-xml-to-other-xml-if-some-element-matches ou pourquoi demandez-vous un nouveau? Et vous êtes censé nous montrer le résultat que vous voulez pour les échantillons que vous avez publiés si vous voulez que nous comprenions ce que vous voulez réaliser, étant donné que votre code ne l'a pas encore fait. –

+0

Comme je ne peux pas supprimer la vieille question, je demande un nouveau avec (j'espère) une meilleure description. – bilak

Répondre

0

Le chemin <xsl:variable name="currentNotifId" select="../NotifId/text()"/> n'est pas correct, devrait être <xsl:variable name="currentNotifId" select="../../NotifId/text()"/>.

Vous pouvez apprendre à utiliser une clé à la place et de mettre simplement la condition dans un schéma de correspondance:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

    <xsl:param name="notifications-source"> 
<Notifications> 
    <Notification> 
     <NotifId>1</NotifId> 
     <MsgText> 
      <![CDATA[notif 1]]> 
     </MsgText> 
    </Notification> 
    <Notification> 
     <NotifId>2</NotifId> 
     <MsgText> 
      <![CDATA[notif 2]]> 
     </MsgText> 
    </Notification> 
</Notifications>   
    </xsl:param> 

    <xsl:key name="note-ref" match="Notification/MsgText" use="../NotifId"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="MsgText[key('note-ref', ../../NotifId, $notifications-source)]"> 
     <xsl:copy-of select="key('note-ref', ../../NotifId, $notifications-source)"/> 
    </xsl:template> 

</xsl:transform> 

en ligne à http://xsltransform.net/93dEHFX.

+0

Merci, je l'ai utilisé mon chemin (avec chemin d'accès fixe) ... quand j'exécute votre modèle dans IDEI IDE, je reçois erreur suivante: [ERREUR]: Impossible de compiler la feuille de style [FATAL]: Erreur de vérification du type de l'expression 'funcall (clé, [literal-expr (note-ref), ParentLocationPath (parentLocationPath (étape ("parent", -1), étape ("parent", -1)), étape ("enfant", 16)), paramètre-ref (notifications-source/référence)] '. ' – bilak

+0

Ce message d'erreur suggère fortement que vous essayez d'utiliser ce code XSLT 2.0 avec un processeur XSLT 1.0 bien que vous nous ayez indiqué que vous utilisiez Saxon 9. –

+0

I' J'utilise saxon 2 en java ... mais je testais quelques fonctionnalités de base dans IDE. Merci d'avoir fait remarquer cela. – bilak