Home > Mobile >  Move XML different elements
Move XML different elements

Time:05-06

I'm trying to move each programme element inside it's corresponding channel element based on attribute id. I tried to create each element manually but they don't have the same child elements, so It would be very long to check for each.

XML :


<tv source-info-url="http://91.121.66.148/">
    <channel id="C1.telerama.fr">
        <display-name>TF1</display-name>
    </channel>
    <channel id="C10.telerama.fr">
        <display-name>TMC</display-name>
    </channel>
    <programme start="20111106195500" stop="20111106200000"
        showview="20564133" channel="C1.telerama.fr">
        <title>Météo</title>
        <desc lang="fr">Bulletin météo et prévisions</desc>
        <category lang="fr">météo</category>
        <length units="minutes">5</length>
        <audio>
            <stereo>stereo</stereo>
        </audio>
    </programme>
    <programme start="20111110053500" stop="20111110060500"
        showview="14730766" channel="C10.telerama.fr">
        <sub-title>La stratégie du lapin</sub-title>
        <desc lang="fr">Episode : 96/156 - Toujours à la recherche d’un
            infaillible moyen de séduction,...</desc>
        <credits>
            <actor>Marie Chevalier (Sabine)</actor>
        </credits>
        <category lang="fr">série</category>
        <category lang="fr">série humoristique</category>
        <length units="minutes">30</length>
    </programme>
</tv>

EXPECTED RESULT

<tv source-info-url="http://91.121.66.148/">
    <channel id="C1.telerama.fr">
        <display-name>TF1</display-name>
        <programme start="20111106195500" stop="20111106200000"
        showview="20564133" channel="C1.telerama.fr">
        <title>Météo</title>
        <desc lang="fr">Bulletin météo et prévisions</desc>
        <category lang="fr">météo</category>
        <length units="minutes">5</length>
        <audio>
            <stereo>stereo</stereo>
        </audio>
    </programme>
    </channel>
    <channel id="C10.telerama.fr">
        <display-name>TMC</display-name>
        <programme start="20111110053500" stop="20111110060500"
        showview="14730766" channel="C10.telerama.fr">
        <sub-title>La stratégie du lapin</sub-title>
        <desc lang="fr">Episode : 96/156 - Toujours à la recherche d’un
            infaillible moyen de séduction,...</desc>
        <credits>
            <actor>Marie Chevalier (Sabine)</actor>
        </credits>
        <category lang="fr">série</category>
        <category lang="fr">série humoristique</category>
        <length units="minutes">30</length>
    </programme>
    </channel>
</tv>

My XSL :

    <xsl:template match="/tv">
        <tv>
            <xsl:for-each select="channel">
                <xsl:element name="channel">
                    <xsl:attribute name = "id">
                        <xsl:value-of select="@id"/>
                    </xsl:attribute>
                    <xsl:element name="display-name">
                        <xsl:value-of select="display-name"/>
                    </xsl:element>
                </xsl:element>
                <!-- Copying programme Elements -->     
                <xsl:call-template name="programmeChannel">
                    <xsl:with-param name="channelID" select = "@id"/>
                </xsl:call-template>
            </xsl:for-each>
        </tv>
    </xsl:template>
    
    
    <xsl:template name = "programmeChannel">
        <xsl:param name="channelID"/>
        <xsl:for-each select="//programme">
            <xsl:if test="@channel=$channelID">
                <xsl:element name="programme">
                    <xsl:attribute name="showview"><xsl:value-of select="@showview"/></xsl:attribute>
                    <xsl:element name="title"><xsl:value-of select="title"/></xsl:element>
                    <xsl:element name="desc">
                        <xsl:attribute name="lang"><xsl:value-of select="desc/@lang"/></xsl:attribute>
                        <xsl:value-of select="title"/>
                    </xsl:element>
                    <xsl:element name="category">
                        <xsl:attribute name="lang"><xsl:value-of select="category/@lang"/></xsl:attribute>
                        <xsl:value-of select="category"/>
                    </xsl:element>
                    <xsl:element name="length">
                        <xsl:attribute name="units"><xsl:value-of select="length/@units"/></xsl:attribute>
                        <xsl:value-of select="length"/>
                    </xsl:element>
                    <xsl:element name="audio">
                        <stereo><xsl:value-of select="audio/stereo"/></stereo>
                    </xsl:element>
                </xsl:element>
            </xsl:if>
        </xsl:for-each>
            
        
    </xsl:template>

CodePudding user response:

This should be easy to do using a key:

XSLT 1.0

<xsl:stylesheet version="1.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="pgm" match="programme" use="@channel" />

<xsl:template match="/tv">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:for-each select="channel">
            <xsl:copy>
                <xsl:copy-of select="@* | *"/>
                <xsl:copy-of select="key('pgm', @id)"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
  • Related