使用xslt进行XML到XML转换,将元素名称替换为属性名称

时间:2017-02-24 09:41:45

标签: xslt

我是xslt的新手,我正在进行xml到xml的转换。请为我提供一个针对以下问题的xslt解决方案。 输入xml如下:

<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>

输出xml需要如下:

<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>

元数据的子节点是动态的,元素名称和元素数量在元数据的每个子节点中将是不同的。 以下是输出文件中的更改:

  1. 用资产替换root / items
  2. 删除元数据标签,元数据的子节点成为项目的直接子项
  3. 当元数据的子节点具有:item元素时,则将元素名称替换为属性item =&#34; album description&#34; 属性值有空格,因此我们需要用下划线替换空格。
  4. 我需要有第3点的解决方案。

    谢谢

1 个答案:

答案 0 :(得分:0)

<?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>