2010-06-23 4 views
1

C'est un peu complexe et je ne le sais pas vraiment si c'est possible. Je suis arrivé ce XML:J'ai besoin d'une transformation XSLT qui sépare les nœuds en fonction d'une comparaison entre les nœuds enfants et qui en résulte un calcul

<XML> 
<member> 
    <InicialAmount>10000000</InitialAmount> 
    <Flows> 
     <Payment> 
      <Date>20100621</Date> 
      <Period> 
       <Amount>10000000</Amount> 
       <StartDate>20100521</StartDate> 
       <EndDate>20100621</EndDate> 
       <contribution> 
        <contributionFlow> 
         <Amount>10000000</Amount> 
         <StartDate>20100521</StartDate> 
         <EndDate>20100621</EndDate> 
        </contributionFlow> 
       </contribution> 
      </Period> 
     </Payment> 
     <Payment> 
      <Date>20100823</Date> 
      <Period> 
       <Amount>9000000</Amount> 
       <StartDate>20100621</StartDate> 
       <EndDate>20100921</EndDate> 
       <contribution> 
        <contributionFlow> 
         <Amount>9000000</Amount> 
         <StartDate>20100621</StartDate> 
         <EndDate>20100721</EndDate> 
        </contributionFlow> 
        <contributionFlow> 
         <Amount>8000000</Amount> 
         <StartDate>20100721</StartDate> 
         <EndDate>20100823</EndDate> 
        </contributionFlow> 
       </contribution> 
      </Period> 
     </Payment> 
    </Flows> 
</member> 

Et je dois faire une transformation (ou plus d'un, le cas échéant) qui me donne ceci:

<XML> 
<Flows> 
    <Flow> 
     <PaymentDate>20100621</PaymentDate> 
     <StartDate>20100521</StartDate> 
     <EndDate>20100621</EndDate> 
     <EventType>C</EventType> 
    </Flow> 
    <Flow> 
     <PaymentDate>20100823</PaymentDate> 
     <StartDate>20100621</StartDate> 
     <EndDate>20100721</EndDate> 
     <EventType>A</EventType> 
     <AmortizationPercent>10.0</AmortizationPercent> 
    </Flow> 
    <Flow> 
     <PaymentDate>20100823</PaymentDate> 
     <StartDate>20100721</StartDate> 
     <EndDate>20100823</EndDate> 
     <EventType>A</EventType> 
     <AmortizationPercent>10.0</AmortizationPercent> 
    </Flow> 
</Flows> 

Il est possible?

Je dois trier chaque <contributionFlow> (qui sera ensuite renommé <Flow>) dans l'une des deux catégories selon un critère.

Pas quelque sorte, vraiment, je dois apporter des changements dans la mise en page, la suppression d'un champ (<Amount>) et la copie un autre à partir du nœud parent (<Date> de <Payment>, qui doit appeler <PaymentDate> dans le nouveau).

En outre, je dois créer un champ <EventType>, qui doivent être remplir avec des informations en fonction de la catégorie du <contributionFlow> se intégrer. Mais, pour savoir dans chaque catégorie, le noeud est placé, je dois faire un calcul.

Je dois vérifier et voir si le champ <Amount> est différent du même champ du <contributionFlow> auparavant (dans le premier, si est différent du champ <InicialAmount>). Dans ce cas, le <EventType> doit être renseigné avec A, sinon, avec C.

Plus, si le <EventType> se révéler A, il y a un calcul à effectuer pour remplir le nœud <AmortizationPercent>.

La valeur <AmortizationPercent> est donnée par la différence entre la valeur <Amount> du <contributionFlow> précédent et courant divisé par <InicialAmount>, tout ce temps 100,0. Je ne sais même pas si cela est possible dans une transformation XSLT, mais pour l'instant, c'est la seule façon de faire fonctionner mon système et c'est comme ça que je dois le faire. Je commence juste à apprendre sur XSLT, donc je trouve difficile de trouver les solutions pour moi-même.

Répondre

2

Ce n'est pas vraiment trop compliqué ... :)

Cette transformation:

<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:variable name="vInitAm" select="/*/InitialAmount"/> 
<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[not(self::Flows or self::contributionFlow) and .//contributionFlow]"> 
    <xsl:apply-templates/> 
</xsl:template> 

<xsl:template match= 
    "Period/*[not(.//contributionFlow)] | Payment/*[not(.//contributionFlow)]"/> 

<xsl:template match="Amount|InitialAmount"/> 

<xsl:template match="contributionFlow"> 
    <Flow> 
    <PaymentDate><xsl:value-of select="../../../Date"/></PaymentDate> 
    <xsl:apply-templates/> 
    <xsl:variable name="vPrevAmount" select= 
     "(preceding::contributionFlow[1]/Amount 
     | 
     $vInitAm 
     ) 
     [last()]"/> 
    <xsl:variable name="vEvType" select= 
    "substring('CA', 1 + not(Amount = $vPrevAmount), 1)"/> 

    <EventType><xsl:value-of select="$vEvType"/></EventType> 

    <xsl:if test="$vEvType = 'A'"> 
     <AmortizationPercent> 
     <xsl:value-of select="($vPrevAmount - Amount)*100 div $vInitAm"/> 
     </AmortizationPercent> 
    </xsl:if> 
    </Flow> 
</xsl:template> 
</xsl:stylesheet> 

lorsqu'il est appliqué sur le document XML fourni (corrigé pour être bien formé):

<member> 
    <InitialAmount>10000000</InitialAmount> 
    <Flows> 
     <Payment> 
      <Date>20100621</Date> 
      <Period> 
       <Amount>10000000</Amount> 
       <StartDate>20100521</StartDate> 
       <EndDate>20100621</EndDate> 
       <contribution> 
        <contributionFlow> 
         <Amount>10000000</Amount> 
         <StartDate>20100521</StartDate> 
         <EndDate>20100621</EndDate> 
        </contributionFlow> 
       </contribution> 
      </Period> 
     </Payment> 
     <Payment> 
      <Date>20100823</Date> 
      <Period> 
       <Amount>9000000</Amount> 
       <StartDate>20100621</StartDate> 
       <EndDate>20100921</EndDate> 
       <contribution> 
        <contributionFlow> 
         <Amount>9000000</Amount> 
         <StartDate>20100621</StartDate> 
         <EndDate>20100721</EndDate> 
        </contributionFlow> 
        <contributionFlow> 
         <Amount>8000000</Amount> 
         <StartDate>20100721</StartDate> 
         <EndDate>20100823</EndDate> 
        </contributionFlow> 
       </contribution> 
      </Period> 
     </Payment> 
    </Flows> 
</member> 

produit le résultat souhaité, correct:

<Flows> 
    <Flow> 
     <PaymentDate>20100621</PaymentDate> 
     <StartDate>20100521</StartDate> 
     <EndDate>20100621</EndDate> 
     <EventType>C</EventType> 
    </Flow> 
    <Flow> 
     <PaymentDate>20100823</PaymentDate> 
     <StartDate>20100621</StartDate> 
     <EndDate>20100721</EndDate> 
     <EventType>A</EventType> 
     <AmortizationPercent>10</AmortizationPercent> 
    </Flow> 
    <Flow> 
     <PaymentDate>20100823</PaymentDate> 
     <StartDate>20100721</StartDate> 
     <EndDate>20100823</EndDate> 
     <EventType>A</EventType> 
     <AmortizationPercent>10</AmortizationPercent> 
    </Flow> 
</Flows> 
Questions connexes