2017-09-01 4 views
0

je le ci-dessous xmlAccès aux nœuds regroupés avec XPath pour construire une sortie constante

<toPay> 
<Pay> 
    <amount>1111</amount>  
    <accountNumber>223128987</accountNumber> 
    <payType>PAYROLL</payType> 
</Pay> 
<Pay> 
    <amount>2222</amount> 
    <accountNumber>123128987</accountNumber> 
    <payType>PAYROLL</payType> 
</Pay> 
<Pay> 
    <amount>333</amount> 
    <accountNumber>645032</accountNumber> 
    <payType>MAIN</payType> 
</Pay> 

J'ai besoin de la sortie dans ce format:

<root> 
<element> 
    <amount>1111</amount> 
    <accountNumber>223128987</accountNumber> 
</element> 
<element> 
    <amount>2222</amount> 
    <accountNumber>223128987</accountNumber> 
</element> 
<element> 
    <amount></amount> 
    <accountNumber></accountNumber> 
</element> 
<element> 
    <amount></amount> 
    <accountNumber></accountNumber> 
</element> 

I ont écrit le code suivant:

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

<xsl:key name="groups" match="payType" use="." /> 

<xsl:template match="/toPay/Pay"> 
    <root> 
     <xsl:apply-templates select="payType[generate-id() = generate-id(key('groups', .)[1])]" /> 
    </root> 
</xsl:template> 

<xsl:template match="payType"> 
    <xsl:variable name="currentGroup" select="." /> 
     <xsl:if test="$currentGroup = 'PAYROLL'"> 

      <xsl:for-each select="key('groups', $currentGroup)"> 
       <element> 
        <xsl:if test="position() = 1"> 
         <amount> 
          <xsl:value-of select="../amount" /> 
         </amount> 
         <accountNumber> 
          <xsl:value-of select="../accountNumber" /> 
         </accountNumber> 
        </xsl:if>     
        <xsl:if test="position() = 2"> 
         <amount> 
          <xsl:value-of select="../amount" /> 
         </amount> 
         <accountNumber> 
          <xsl:value-of select="../accountNumber" /> 
         </accountNumber> 
        </xsl:if> 
       </element> 
      </xsl:for-each> 
     </xsl:if> 
</xsl:template> 

Mais la question que je suis confronté est que - je ne peux pas accéder aux nœuds regroupés pour paytype -PAYROLL. La seule façon que je sais est avec la position mais mon exigence d'entrer toujours 4 noeuds d'élément toujours dans la sortie si les noeuds dans le xml source avec PAYtype -PAYROLL existent ou non. S'il existe, alors les valeurs des mêmes eeds doivent être remplies sinon les étiquettes xml sans valeurs.

Toute aide est très appréciée - soit xslt 1.0 ou 2.0.

+0

Veuillez expliquer la logique requise en mots. Je ne comprends pas votre sortie du tout. –

+0

Votre modèle crée un élément de résultat 'group' alors que la sortie désirée n'affiche aucun de ces éléments. Vous devrez donc expliquer plus en détail ce que vous voulez implémenter. Avez-vous besoin de quatre éléments 'element' dans chaque élément de résultat' group' ou quatre 'element' dans le résultat complet? –

+0

Dans la sortie, il devrait toujours y avoir 4 nœuds d'éléments. Chaque nœud d'élément doit être rempli avec les valeurs du nœud xml source Pay où le payType est PAYROLL. Dans le cas où il y a 2 nœuds de paye avec payType comme PAYROLL alors la sortie devrait avoir 2 premiers nœuds d'élément avec des valeurs provenant du xml source et les 2 nœuds d'élément restants avec des balises xml montant et numéro de compte avec des valeurs vides. – Vicky

Répondre

1

Si je comprends bien votre explication correctement, vous pouvez faire quelque chose très simple - même si un peu primitive:

<xsl:template match="/toPay"> 
    <xsl:variable name="payroll" select="Pay[payType='PAYROLL']" /> 
    <root> 
     <element> 
      <amount> 
       <xsl:value-of select="$payroll[1]/amount" /> 
      </amount> 
      <accountNumber> 
       <xsl:value-of select="$payroll[1]/accountNumber" />   
      </accountNumber> 
     </element> 
     <element> 
      <amount> 
       <xsl:value-of select="$payroll[2]/amount" /> 
      </amount> 
      <accountNumber> 
       <xsl:value-of select="$payroll[2]/accountNumber" />   
      </accountNumber> 
     </element> 
     <element> 
      <amount> 
       <xsl:value-of select="$payroll[3]/amount" /> 
      </amount> 
      <accountNumber> 
       <xsl:value-of select="$payroll[3]/accountNumber" />   
      </accountNumber> 
     </element> 
     <element> 
      <amount> 
       <xsl:value-of select="$payroll[4]/amount" /> 
      </amount> 
      <accountNumber> 
       <xsl:value-of select="$payroll[4]/accountNumber" />   
      </accountNumber> 
     </element> 
    </root> 
</xsl:template> 

Je ne vois aucune exigence de regroupement de quoi que ce soit.


Voici un peu la version plus élégante:

XSLT 2,0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/toPay"> 
    <xsl:variable name="payroll" select="Pay[payType='PAYROLL']" /> 
    <root> 
     <xsl:apply-templates select="$payroll"/> 
     <xsl:for-each select="1 to 4 - count($payroll)"> 
      <element> 
       <amount/> 
       <accountNumber/> 
       </element> 
     </xsl:for-each> 
    </root> 
</xsl:template> 

<xsl:template match="Pay"> 
    <element> 
     <xsl:copy-of select="amount, accountNumber"/> 
    </element> 
</xsl:template> 

</xsl:stylesheet> 

Démo: http://xsltransform.net/6pS1zDr

+0

fonctionne pour moi merci – Vicky

+0

@Vicky Si votre question est traitée, s'il vous plaît fermez-le en acceptant la réponse. –

1

Je vois aussi pas besoin de regroupement, si vous voulez sortie vide éléments pour les éléments qui ne sont pas présents alors avec XSLT 2.0, vous pouvez utiliser

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

    <xsl:output indent="yes"/> 

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

    <xsl:template match="toPay"> 
     <root> 
      <xsl:variable name="payroll" select="Pay[payType = 'PAYROLL']"/> 
      <xsl:apply-templates select="$payroll"/> 
      <xsl:for-each select="(count($payroll) + 1) to 4"> 
       <element> 
       <amount></amount> 
       <accountNumber></accountNumber> 
      </element> 
      </xsl:for-each> 
     </root> 
    </xsl:template> 

    <xsl:template match="Pay"> 
     <element> 
      <xsl:apply-templates select="* except payType"/> 
     </element> 
    </xsl:template> 
</xsl:transform>