2010-01-13 7 views
2

je dois trier seulement les <Transaction-Detail> noeuds (par le nœud enfant <tran-id>) du fichier suivant:tri seulement noeuds XML spécifiques

<TransActDO clear="true" removed="false"> 
    <stmt-reason-code>1001</stmt-reason-code> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>788.20</txn-amt> 
    <txn-description>New Purchase</txn-description> 
    <tran-id>3271</tran-id> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>-68.20</txn-amt> 
    <txn-description>Return</txn-description> 
    <tran-id>27795</tran-id> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>0.00</txn-amt> 
    <txn-description>Comment</txn-description> 
    <transaction-reason-desc>No Reason</transaction-reason-desc> 
    <tran-id>13365</tran-id> 
    <transaction-reason-code>0</transaction-reason-code> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>343.45</txn-amt> 
    <txn-description>New Purchase</txn-description> 
    <tran-id>7558</tran-id> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>0.00</txn-amt> 
    <txn-description>Comment</txn-description> 
    <transaction-reason-desc>No Reason</transaction-reason-desc> 
    <tran-id>6512</tran-id> 
    <transaction-reason-code>0</transaction-reason-code> 
    </Transaction-Detail> 
    <account-no>123456789</account-no> 
    <payer-name>JOHN DOE</payer-name> 
    <Product-Detail clear="true" removed="false"> 
    <Name>WIDGET</Name> 
    <Amount>89.00</Amount> 
    </Product-Detail> 
    <Product-Detail clear="true" removed="false"> 
    <Name>NEWER WIDGET</Name> 
    <Amount>99.99</Amount> 
    </Product-Detail> 
    <stmt-reason-desc>Web Statement</stmt-reason-desc> 
    <type>Original</type> 
</TransActDO> 

La sortie est XML et doit également copier tous les autres noeuds et attributs de le fichier original. Pour l'essentiel, copiez tout, il suffit de trier les noeuds Transaction-Detail.

J'ai jusqu'ici:

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

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

    <xsl:template match="TransActDO"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="Transaction-Detail"> 
     <xsl:sort select="tran-id" data-type="number" order="ascending"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Il en résulte un fichier XML correctement triés contenant uniquement les nœuds Transaction-Détail et leurs nœuds enfants. Quand jamais je tente d'ajouter une logique supplémentaire pour copier le reste des noeuds, le tri se brise. Je suppose que j'ai de la difficulté à faire le tour de mon cerveau autour de la théorie et de la syntaxe d'exécution de XSLT.

Toute aide est très appréciée!
-nth-

+0

Vous avez besoin des nœuds qui Preced l'ensemble des noeuds de transaction-Détail de rester au sommet et celles qui suivent pour rester au bas ou cant noeuds Transaction-Détail déplacer à la bas du XMl? (BTW je suppose pour des raisons héritées que vous ne pouvez pas simplement re-concevoir le XML pour que des choses comme Product-Detail et Transaction-Detail aient chacune un nœud parent contenant ainsi ils n'ont pas de frères avec différentes tagnames) – AnthonyWJones

Répondre

4

Cela fera: -

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" encoding="Windows-1252" /> 

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

    <xsl:template match="TransActDO"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[not(preceding-sibling::Transaction-Detail) and not(self::Transaction-Detail)]"/> 
      <xsl:apply-templates select="Transaction-Detail"> 
       <xsl:sort select="tran-id" data-type="number" order="ascending"/> 
      </xsl:apply-templates> 
      <xsl:apply-templates select="@*|node()[not(following-sibling::Transaction-Detail) and not(self::Transaction-Detail)]"/> 
    </xsl:copy> 
    </xsl:template> 


</xsl:stylesheet> 

Si vous ne me dérange pas de déplacer les éléments détails de la transaction soit en haut ou en bas de l'élément TransActDO vous pouvez simplifier le jeu intérieur d'appliquer des modèles à: -

  <xsl:apply-templates select="@*|node()[not(self::Transaction-Detail)]"/> 
      <xsl:apply-templates select="Transaction-Detail"> 
       <xsl:sort select="tran-id" data-type="number" order="ascending"/> 
      </xsl:apply-templates> 
+0

+1 . Je viens juste de remarquer que vous avez posté le code * exact * que je viens de publier (j'aurais dû lire votre second exemple de code ...). Suppression de ma réponse pour éviter la redondance – Tomalak

+0

Merci Anthony. Cela a bien marché! Malheureusement, je ne contrôle pas la création de la structure xml mais cela, au moins, résoudra le problème du tri. – nth

Questions connexes