2017-09-10 2 views
1

Je suis novice dans la transformation XSLT et j'ai des connaissances très basiques. Je cherche votre aide. J'ai un fichier XML s'il vous plaît voir l'exemple ci-dessous. Je voudrais diviser ce fichier en plusieurs fichiers plus petits.Transformation XSLT: grouper et diviser le fichier en plusieurs parties

Je voudrais regrouper en fonction de la valeur de cmfp: future et cmfp: citation.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<GuiRoot xmlns:cmfp="mx.MarketParameters.Fixing.Commodities.Futures" xmlns:mp="mx.MarketParameters" xmlns:fg="mx.MarketParameters.Fixing" xmlns:fgrt="mx.MarketParameters.Fixing.IRIndices" xmlns:xc="xmlCache" xmlns:fgfx="mx.MarketParameters.Fixing.FXIndices" xmlns:cmip="mx.MarketParameters.Commodities.Indices"> 
<xc:XmlCache xc:action="Update"> 
    <xc:XmlCacheArea xc:value="MarketParameters"> 
    <mp:nickName xc:subset="Reference" xc:value="./BORATES"> 
    <mp:date xc:value="20161202"> 
    <fg:fixing> 
     <cmfp:futurePrice> 
     <cmfp:future xc:value="ONE"> 
     <cmfp:quotation xc:value="1.1"> 
     <cmfp:maturity xc:value="1.1.1"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13405.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     </cmfp:future> 
     <cmfp:future xc:value="ONE"> 
     <cmfp:quotation xc:value="1.2"> 
     <cmfp:maturity xc:value="1.2.1"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13405.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     <cmfp:quotation xc:value="1.2"> 
     <cmfp:maturity xc:value="1.2.2"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13406.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     </cmfp:future> 
     <cmfp:future xc:value="TWO"> 
     <cmfp:quotation xc:value="2.1"> 
     <cmfp:maturity xc:value="2.1.1"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13405.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     </cmfp:future> 
     <cmfp:future xc:value="THREE"> 
     <cmfp:quotation xc:value="3.1"> 
     <cmfp:maturity xc:value="3.1.1"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13405.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     </cmfp:future> 
     <cmfp:future xc:value="FOUR"> 
     <cmfp:quotation xc:value="4.1"> 
     <cmfp:maturity xc:value="4.1.1"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13405.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     </cmfp:future> 
     <cmfp:future xc:value="EIGHT"> 
     <cmfp:quotation xc:value="8.1"> 
     <cmfp:maturity xc:value="8.1.1"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13405.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     </cmfp:future> 
     </cmfp:futurePrice> 
    </fg:fixing> 
    </mp:date> 
    </mp:nickName> 
    </xc:XmlCacheArea> 
</xc:XmlCache> 
</GuiRoot> 

sortie désirée File1

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<GuiRoot xmlns:cmfp="mx.MarketParameters.Fixing.Commodities.Futures" xmlns:mp="mx.MarketParameters" xmlns:fg="mx.MarketParameters.Fixing" xmlns:fgrt="mx.MarketParameters.Fixing.IRIndices" xmlns:xc="xmlCache" xmlns:fgfx="mx.MarketParameters.Fixing.FXIndices" xmlns:cmip="mx.MarketParameters.Commodities.Indices"> 
<xc:XmlCache xc:action="Update"> 
    <xc:XmlCacheArea xc:value="MarketParameters"> 
    <mp:nickName xc:subset="Reference" xc:value="./BORATES"> 
    <mp:date xc:value="20161202"> 
    <fg:fixing> 
     <cmfp:futurePrice> 
     <cmfp:future xc:value="ONE"> 
     <cmfp:quotation xc:value="1.1"> 
     <cmfp:maturity xc:value="1.1.1"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13405.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     <cmfp:quotation xc:value="1.2"> 
     <cmfp:maturity xc:value="1.2.1"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13405.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     <cmfp:maturity xc:value="1.2.2"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13406.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     </cmfp:future> 
     <cmfp:future xc:value="FOUR"> 
     <cmfp:quotation xc:value="4.1"> 
     <cmfp:maturity xc:value="4.1.1"> 
      <cmfp:column xc:value="CLOSE" xc:type="Fields"> 
      <mp:HisValue xc:keyFormat="C">[startDate="19990101"][endDate="19990101"]13405.00</mp:HisValue> 
      </cmfp:column> 
     </cmfp:maturity> 
     </cmfp:quotation> 
     </cmfp:future> 
     </cmfp:futurePrice> 
    </fg:fixing> 
    </mp:date> 
    </mp:nickName> 
    </xc:XmlCacheArea> 
</xc:XmlCache> 
</GuiRoot> 

File2 simlar pour déposer 1 mais différents noeuds sur la base de résultat mod .....

Fichier3 simlar fichier 1 mais différents noeuds en fonction des résultats mod .....

appriciate votre aide ... merci à l'avance

J'ai essayé avec le code ci-dessous XSLT mais sa ne me donne pas la sortie désirée ....

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cmfp="mx.MarketParameters.Fixing.Commodities.Futures" xmlns:mp="mx.MarketParameters" xmlns:fg="mx.MarketParameters.Fixing" xmlns:fgrt="mx.MarketParameters.Fixing.IRIndices" xmlns:xc="xmlCache" xmlns:fgfx="mx.MarketParameters.Fixing.FXIndices" xmlns:cmip="mx.MarketParameters.Commodities.Indices" exclude-result-prefixes="cmfp mp fg fgrt xc fgfx cmip"> 
<xsl:output method="xml" version="1.0" omit-xml-declaration="no" standalone="yes" encoding="UTF-8" indent="yes"/> 
<!-- define variables [start] --> 
<xsl:variable name="action" select="/GuiRoot/xc:XmlCache/@xc:action"/> 
<xsl:variable name="nickname" select="/GuiRoot/xc:XmlCache/xc:XmlCacheArea/mp:nickName/@xc:value"/> 
<xsl:variable name="mpdate" select="/GuiRoot/xc:XmlCache/xc:XmlCacheArea/mp:nickName/mp:date/@xc:value"/> 
<xsl:variable name="noOfSplits" select="3"/> 
<!-- define variables [ end ]--> 
<xsl:template match="cmfp:futurePrice"> 
    <xsl:apply-templates select="cmfp:futurePrice"/> 
    <xsl:for-each-group select="cmfp:future" group-by="(position() -1) mod $noOfSplits"> 
    <xsl:variable name="file_name" select="format-number(current-grouping-key(),'000')"/> 
    <xsl:result-document href="files/cmfp_SPLIT_{$file_name}.xml"> 
    <GuiRoot xmlns:cmfp="mx.MarketParameters.Fixing.Commodities.Futures" xmlns:mp="mx.MarketParameters" xmlns:fg="mx.MarketParameters.Fixing" xmlns:fgrt="mx.MarketParameters.Fixing.IRIndices" xmlns:xc="xmlCache" xmlns:fgfx="mx.MarketParameters.Fixing.FXIndices" xmlns:cmip="mx.MarketParameters.Commodities.Indices"> 
    <xc:XmlCache> 
     <xsl:attribute name="xc:action"> 
     <xsl:value-of select="$action"/> 
     </xsl:attribute> 
     <xc:XmlCacheArea xc:value="MarketParameters"> 
     <mp:nickName xc:subset="Reference"> 
     <xsl:attribute name="xc:value"> 
     <xsl:value-of select="$nickname"/> 
     </xsl:attribute> 
     <mp:date> 
     <xsl:attribute name="xc:value"> 
      <xsl:value-of select="$mpdate"/> 
     </xsl:attribute> 
     <fg:fixing> 
      <cmfp:futurePrice> 
      <xsl:copy-of select="current-group()"/> 
      </cmfp:futurePrice> 
     </fg:fixing> 
     </mp:date> 
     </mp:nickName> 
     </xc:XmlCacheArea> 
    </xc:XmlCache> 
    </GuiRoot> 
    </xsl:result-document> 
    </xsl:for-each-group> 
</xsl:template> 
</xsl:stylesheet> 
+0

Pouvez-vous expliquer plus en détail quels sont les critères de fractionnement? Pourquoi le premier fichier de résultat a 'cmfp: future xc: value =" ONE "' et 'cmfp: future xc: value =" FOUR "' mais il y a deux fichiers différents pour les valeurs 'TWO' et' THREE'? –

+0

Merci Martin. Je viens de réaliser que j'ai donné un mauvais fichier d'entrée. Fondamentalement, j'ai besoin de groupe basé sur cmfp: future et cmfp: devis. J'ai utilisé la fonction de mod simple basée sur la position de noeud .... – PanduranG

+0

Dans l'exemple uniq cmfp: avenir sont UN, DEUX, TROIS, QUATRE et HUIT c.-à-d. Total 5 valeurs uniq. Si je choisis la fonction mod ONE & FOUR sera dans le même fichier. DEUX et HUIT dans le même fichier et TROIS seront dans un fichier séparé. J'espère que cela clarifie. Merci encore! – PanduranG

Répondre

1

Je pense que vous devez d'abord groupe et vous pouvez diviser en fonction de la position, ce qui suit est une tentative avec XSLT 3.0 (comme soutenu par Saxon 9.8 (toutes les éditions) ou 9,7 PE et EE):

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    xpath-default-namespace="mx.MarketParameters.Fixing.Commodities.Futures" 
    xmlns:xc="xmlCache" 
    exclude-result-prefixes="xs math" 
    version="3.0"> 

    <xsl:output indent="yes"/> 

    <xsl:mode on-no-match="shallow-copy"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="noOfSplits" select="3"/> 

    <xsl:template match="/"> 
     <xsl:variable name="original-root-element" select="*"/> 
     <xsl:variable name="groups"> 
      <xsl:for-each-group select="//future" group-by="@xc:value"> 
       <xsl:copy> 
        <xsl:copy-of select="@*"/> 
        <xsl:for-each-group select="current-group()/quotation" group-by="@xc:value"> 
         <xsl:copy> 
          <xsl:copy-of select="@*, current-group()/node()"/> 
         </xsl:copy> 
        </xsl:for-each-group> 
       </xsl:copy> 
      </xsl:for-each-group> 
     </xsl:variable> 
     <xsl:for-each-group select="$groups/future" group-by="(position() - 1) mod $noOfSplits"> 
      <xsl:result-document href="split{position()}.xml"> 
      <xsl:apply-templates select="$original-root-element"> 
       <xsl:with-param name="contents" select="current-group()" tunnel="yes"/> 
      </xsl:apply-templates> 
      </xsl:result-document> 
     </xsl:for-each-group> 
    </xsl:template> 

    <xsl:template match="futurePrice"> 
     <xsl:param name="contents" tunnel="yes"/> 
     <xsl:copy> 
      <xsl:copy-of select="$contents"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Pour exécuter avec un processeur XSLT 2.0 comme les anciennes versions de Saxon 9, vous devez épeler la copie de l'identité de transformation peu profonde avec par exemple

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

au lieu d'utiliser xsl:mode.

+0

Merci beaucoup @Martin Honnen – PanduranG