2016-08-26 1 views
0

Je XML avec ce players et citizens sections. Chaque section a plusieurs étiquettes person.transformation XSLT groupe balises similaires

<?xml version="1.0" encoding="UTF-8"?> 
<test> 
    <players> 
     <person> 
     <name>joe</name> 
     <age>20</age> 
     </person> 
     <person> 
     <name>sam</name> 
     <age>23</age> 
     </person> 
    </players> 
    <citizens> 
     <person> 
     <name>joe</name> 
     <city>ny</city> 
     </person> 
     <person> 
     <name>sam</name> 
     <city>london</city> 
     </person> 
    </citizens> 
</test> 

Maintenant, je veux transformer cela pour que person étiquettes de, players et citizens sections sont fusionnées en fonction de tag name.

C'est la sortie que j'ai besoin.

<?xml version="1.0" encoding="UTF-8"?> 
<test> 
    <players> 
     <person> 
     <name>joe</name> 
     <age>20</age> 
     <city>ny</city> 
     </person> 
     <person> 
     <name>sam</name> 
     <age>23</age> 
     <city>london</city> 
     </person> 
    </players> 
</test> 

Je souhaite effectuer une transformation XSLT pour cela. J'ai essayé beaucoup de choses sans chance. Appréciez un peu d'aide pour cela.

Mise à jour: J'ai essayé.

<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="citizens" select="/test/citizens"/> 
    <xsl:template match="/test/players"> 
     <players> 
      <xsl:apply-templates select="person"/> 
     </players> 
    </xsl:template> 

    <xsl:template match="person"> 
     <xsl:variable name="data1" select="."/> 
     <xsl:variable name="data2" select="/test/citizens/person[name=current()/name]/."/> 
     <person> 
      <xsl:copy-of select="$data1/*"/> 
      <xsl:for-each select="$data2/*"> 
       <xsl:variable name="element2" select="name(.)"/> 
       <xsl:if test="count($data1/*[name()=$element2])=0"> 
        <xsl:copy-of select="."/> 
       </xsl:if> 
      </xsl:for-each> 
     </person> 
    </xsl:template> 
</xsl:stylesheet> 

C'est presque correct. Je veux juste me débarrasser des 2 dernières étiquettes person. Guidez-moi s'il-vous-plaît.

<players> 
     <person> 
     <name>joe</name> 
     <age>20</age> 
     <city>ny</city> 
     </person> 
     <person> 
     <name>sam</name> 
     <age>23</age> 
     <city>london</city> 
     </person> 
    </players> 
    <person> 
     <name>joe</name> 
     <city>ny</city> 
    </person> 
    <person> 
     <name>sam</name> 
     <city>london</city> 
    </person> 
+0

J'ai trouvé beaucoup de différents types d'exemples de regroupement. Mais n'a pas trouvé celui-ci. – abhi

+0

Quelle version de XSLT votre processeur prend-il en charge? –

+0

je peux utiliser soit – abhi

Répondre

1

est ici d'une manière que vous pourriez regarder:

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:key name="person-by-name" match="person" use="name" /> 

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

<xsl:template match="/test"> 
    <xsl:copy> 
     <xsl:apply-templates select="players"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="person"> 
    <xsl:copy> 
     <xsl:apply-templates/> 
     <xsl:copy-of select="key('person-by-name', name, ../../citizens)/city "/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

Voici une autre:

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:template match="/test"> 
    <xsl:copy> 
     <players> 
      <xsl:for-each-group select="*/person" group-by="name"> 
       <person> 
        <xsl:copy-of select="name"/> 
        <xsl:copy-of select="current-group()/*[not(self::name)]"/> 
       </person> 
      </xsl:for-each-group> 
     </players> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
+0

Merci beaucoup. J'essayais aussi, et mis à jour ma question avec ce que j'ai obtenu jusqu'à présent. Pourriez-vous s'il vous plaît m'aider à comprendre ce que je devrais changer dans le mien? – abhi

+0

Pourriez-vous s'il vous plaît l'éditer et le poster comme autre réponse? – abhi

+0

@abhi J'ai peur de ne pas comprendre votre approche et je ne sais pas comment la réparer. –