1
votes

I am new to xslt, I am working on an xml to xml transformation. Please provide me an xslt solution for the below problem. Input xml is as below:

<root type="object">
    <items type="array">
        <item type="object">
            <original_file_name type="string">filename-m.mp3</original_file_name>
            <description type="string">some description text</description>
            <created_at type="string">2017-02-20T20:52:52Z</created_at>
            <metadata type="object">
                <guest type="string">guestname here</guest>
                <webInfo type="string">http://abc</webInfo>
                <title type="string">title text testing</title>
                <airDate type="string">2017-02-21</airDate>
            </metadata>
            <status type="string">live</status>
            <asset_type type="string">video</asset_type>
            <player_id type="string">391e099a718f4a62b44c78f97f85ecde</player_id>
            <name type="string">title</name>
        </item>
        <item type="object">
            <original_file_name type="string">filename-m.mp3111</original_file_name>
            <description type="string">some description text test</description>
            <created_at type="string">2015-02-20T20:52:52Z</created_at>
            <metadata type="object">
                <guest type="string">guestname here 1111</guest>
                <webInfo type="string">http://abc</webInfo>
                <a:item type="string" item="album description" xmlns:a="item">test description album</a:item>
                <a:item type="string" item="album order" xmlns:a="item">106</a:item>
            </metadata>
            <status type="string">live</status>
            <asset_type type="string">video</asset_type>
            <player_id type="string">391e099a718f4a62b44c78f97f85ecdea</player_id>
            <name type="string">title1</name>        
        </item>
    </items>
</root>

Output xml needs to be as below:

<assets>
    <item>
        <original_file_name>filename-m.mp3</original_file_name>
        <description>some description text</description>
        <created_at>2017-02-20T20:52:52Z</created_at>
        <guest>guestname here</guest>
        <webInfo>http://abc</webInfo>
        <title>title text testing</title>
        <airDate>2017-02-21</airDate>
        <status type="string">live</status>
        <asset_type type="string">video</asset_type>
        <player_id type="string">391e099a718f4a62b44c78f97f85ecde</player_id>
        <name type="string">title</name>
    </item>
    <item>
        <original_file_name>filename-m.mp3111</original_file_name>
        <description>some description text test</description>
        <created_at>2015-02-20T20:52:52Z</created_at>
        <guest>guestname here 1111</guest>
        <webInfo>http://abc</webInfo>
        <album_description>test description album</album_description>
        <album_order>106</album_order>
        <status type="string">live</status>
        <asset_type type="string">video</asset_type>
        <player_id type="string">391e099a718f4a62b44c78f97f85ecdea</player_id>
        <name type="string">title1</name>
    </item>
</assets>

The child nodes of metadata is dynamic, element names and number of elements will be different in each child nodes of metadata. Below are the changes in output file:

  1. Replace root/items with assets
  2. Remove the metadata tag and child nodes of metadata becomes the direct child of item
  3. When child nodes of metadata has a:item elements then replace the element name with attribute item="album description" Attribute value is having spaces, so we need to replace spaces with underscore.

I need to have solution for point number 3.

Thank you

1

1 Answers

0
votes
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:a="item">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- replace root/items with assets -->
<xsl:template match="root/items">
  <xsl:element name="assets">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

<!-- for some elements, copy only inner nodes, not attributes -->
<xsl:template match="item|original_file_name|description|created_at|guest|webInfo|title|airDate">
    <xsl:copy>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

<!-- for metadata tag replace it with its children -->
<xsl:template match="metadata">    
    <xsl:apply-templates select="node()"/>
</xsl:template>

<!-- for a:item tag emit new element with name taken from item attribute -->
<xsl:template match="a:item">    
    <xsl:element name="{translate(@item, ' ', '_')}">
     <xsl:apply-templates select="node()"/>
   </xsl:element>
</xsl:template>

<!--Identity template, provides default behavior that copies all content into the output -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>