2017-06-30 1 views
0

J'ai le code XML d'entrée suivante:Regroupement quand une touche avec le même nom existe à différents niveaux en utilisant XSLT 1.0

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <results> 
     <case> 
     <KEY>c1</KEY> 
     <issue> 
      <KEY>i1</KEY> 
      <id>Apple</id> 
     </issue> 
     <issue> 
      <KEY>i1</KEY> 
      <id>Orange</id> 
     </issue> 
     <issue> 
      <KEY>i2</KEY> 
      <id>Mango</id> 
     </issue> 
     </case> 
     <case> 
     <KEY>c1</KEY> 
     <issue> 
      <KEY>i5</KEY> 
      <id>Apricot</id> 
     </issue> 
     <issue> 
      <KEY>i5</KEY> 
      <id>Blueberry</id> 
     </issue> 
     <issue> 
      <KEY>i6</KEY> 
      <id>blackberry</id> 
     </issue> 
     </case> 
     <case> 
     <KEY>c2</KEY> 
     <issue> 
      <KEY>i3</KEY> 
      <id>Banana</id> 
     </issue> 
     <issue> 
      <KEY>i3</KEY> 
      <id>Cherry</id> 
     </issue> 
     <issue> 
      <KEY>i4</KEY> 
      <id>Grapes</id> 
     </issue> 
     </case> 
    </results> 
</root> 

Maintenant, je veux groupe par <KEY> de <case> d'abord, puis par <KEY> de <issue>. L'idée est de regrouper tous les <issue> par leur clé d'émission et leur clé. Enfin, je veux déplacer tous les <id> dont les clés de sortie sont identiques sous le nœud <sourceInstance> dans le <issue>.

Mon xml de sortie doit être comme ci-dessous:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <results> 
     <case> 
     <KEY>c1</KEY> 
     <issue> 
      <KEY>i1</KEY> 
      <sources> 
       <sourceInstance> 
        <id>Apple</id> 
       </sourceInstance> 
       <sourceInstance> 
        <id>Orange</id> 
       </sourceInstance> 
      </sources> 
     </issue> 
     <issue> 
      <KEY>i2</KEY> 
      <sources> 
       <sourceInstance> 
        <id>Mango</id> 
       </sourceInstance> 
      </sources> 
     </issue> 
     <issue> 
      <KEY>i5</KEY> 
      <sources> 
       <sourceInstance> 
        <id>Apricot</id> 
       </sourceInstance> 
       <sourceInstance> 
        <id>Blueberry</id> 
       </sourceInstance> 
      </sources> 
     </issue> 
     <issue> 
      <KEY>i6</KEY> 
      <sources> 
       <sourceInstance> 
        <id>Apple</id> 
       </sourceInstance> 
       <sourceInstance> 
        <id>Orange</id> 
       </sourceInstance> 
      </sources> 
     </issue> 
     </case> 
     <case> 
     <KEY>c2</KEY> 
     <issue> 
      <KEY>i3</KEY> 
      <sources> 
       <sourceInstance> 
        <id>Banana</id> 
       </sourceInstance> 
       <sourceInstance> 
        <id>Cherry</id> 
       </sourceInstance> 
      </sources> 
     </issue> 
     <issue> 
      <KEY>i4</KEY> 
      <sources> 
       <sourceInstance> 
        <id>Grapes</id> 
       </sourceInstance> 
      </sources> 
     </issue> 
     </case> 
    </results> 
</root> 

J'ai essayé en utilisant le XSLT suivant, mais n'a pas pu obtenir la sortie xml souhaitée.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:key name="case" match="case" use="string(KEY)" /> 
    <xsl:key name="issue" match="case" use="concat(KEY, '|', KEY)" /> 
    <xsl:template match="results"> 
     <xsl:copy> 
     <xsl:apply-templates select="case[generate-id() = generate-id(key('case', string(KEY))[1])]" mode="case" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="case" mode="case"> 
     <xsl:choose> 
     <xsl:when test="KEY"> 
      <case> 
       <xsl:copy-of select="KEY" /> 
       <xsl:apply-templates select="key('case', KEY)[generate-id() = generate-id(key('issue', concat(KEY, '|', KEY))[1])]" mode="issue" /> 
      </case> 
     </xsl:when> 
     </xsl:choose> 
    </xsl:template> 
    <xsl:template match="case " mode="issue"> 
     <xsl:choose> 
     <xsl:when test="KEY"> 
      <issue> 
       <xsl:copy-of select="KEY" /> 
       <sources> 
        <xsl:apply-templates select="key('issue', id)" /> 
       </sources> 
      </issue> 
     </xsl:when> 
     </xsl:choose> 
    </xsl:template> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="case"> 
     <sourceInstance> 
     <id> 
      <xsl:value-of select="id" /> 
     </id> 
     </sourceInstance> 
    </xsl:template> 
</xsl:stylesheet> 

Il semble que je suis incapable de cadrer la combinaison correcte d'une clé à l'aide du <KEY> de <case> et <issue> comme le nœud du même nom (à savoir <KEY>) existe à la fois les lieux. Est-ce que quelqu'un peut me dire ce que je manque dans mon XSLT?

Répondre

2

Le principal problème est la définition de votre clé de issue

<xsl:key name="issue" match="case" use="concat(KEY, '|', KEY)" /> 

Vous devez être assortit issue éléments ici, et en utilisant une concaténation de la clé pour issue et l'élément parent case

<xsl:key name="issue" match="issue" use="concat(KEY, '|', ../KEY)" /> 

Ensuite, pour obtenir les éléments groupés issue pour une clé donnée case, vous feriez cela ...

<xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" /> 

Essayez cette XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:key name="case" match="case" use="string(KEY)" /> 
    <xsl:key name="issue" match="issue" use="concat(KEY, '|', ../KEY)" /> 

    <xsl:template match="results"> 
     <xsl:copy> 
     <xsl:apply-templates select="case[generate-id() = generate-id(key('case', string(KEY))[1])]" mode="case" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="case" mode="case"> 
     <xsl:choose> 
     <xsl:when test="KEY"> 
      <case> 
       <xsl:copy-of select="KEY" /> 
       <xsl:apply-templates select="key('case', KEY)/issue[generate-id() = generate-id(key('issue', concat(KEY, '|', ../KEY))[1])]" mode="issue" /> 
      </case> 
     </xsl:when> 
     </xsl:choose> 
    </xsl:template> 

    <xsl:template match="issue" mode="issue"> 
     <xsl:choose> 
     <xsl:when test="KEY"> 
      <issue> 
       <xsl:copy-of select="KEY" /> 
       <sources> 
        <xsl:apply-templates select="key('issue', concat(KEY, '|', ../KEY))" /> 
       </sources> 
      </issue> 
     </xsl:when> 
     </xsl:choose> 
    </xsl:template> 

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

    <xsl:template match="issue"> 
     <sourceInstance> 
     <id> 
      <xsl:value-of select="id" /> 
     </id> 
     </sourceInstance> 
    </xsl:template> 
</xsl:stylesheet> 
+0

C'est parfait! +1 pour votre réponse rapide –