XML转换

时间:2017-05-24 13:42:48

标签: xml xslt

我需要使用xslt将xml文件转换为另一个xml文件。 输入文件如下:

<root type="object">
    <items type="array">
        <item type="object">
            <updated_at type="string">2017-05-20</updated_at>
            <external_id type="null"></external_id>
            <created_at type="string">2017-05-20</created_at>
            <embed_code type="string">ec111</embed_code>
            <status type="string">live</status>
            <content_type type="string">video</content_type>
            <name type="string"></name>
            <hosted_at type="null"></hosted_at>
        </item>
        <item type="object">
            <updated_at type="string">2017-05-19</updated_at>
            <external_id type="null"></external_id>
            <labels type="array">
                <item type="object">
                    <name type="string">lbl name 1</name>
                    <full_name type="string">full lbl name 1</full_name>
                    <id type="string">lbl1</id>
                    <parent_id type="string">parent_id_1</parent_id>
                </item>
            </labels>
            <created_at type="string">2017-05-20</created_at>
            <embed_code type="string">ec112</embed_code>
            <status type="string">live</status>
            <content_type type="string">video</content_type>
            <name type="string">test</name>
            <hosted_at type="null"></hosted_at>
        </item>
        <item type="object">
            <updated_at type="string">2017-05-19</updated_at>
            <external_id type="null"></external_id>
            <labels type="array">
                <item type="object">
                    <name type="string">lbl name 2</name>
                    <full_name type="string">full lbl name 2</full_name>
                    <id type="string">lbl2</id>
                    <parent_id type="string">parent_id_2</parent_id>
                </item>
                <item type="object">
                    <name type="string">lbl name 3</name>
                    <full_name type="string">full lbl name 3</full_name>
                    <id type="string">lbl3</id>
                    <parent_id type="string">parent_id_3</parent_id>
                </item>
            </labels>
            <created_at type="string">2017-05-20</created_at>
            <embed_code type="string">ec113</embed_code>
            <status type="string">live</status>
            <content_type type="string">video</content_type>
            <name type="string">testing</name>
            <hosted_at type="null"></hosted_at>
        </item>
    </items>
</root>

需要将上述xml转换为以下格式:

<?xml version="1.0"?>
<labels>
    <item>
        <embed_code>ec112</embed_code>
        <name>lbl name 1</name>
        <full_name>full lbl name 1</full_name>
        <id>lbl1</id>
        <parent_id>parent_id_1</parent_id>
    </item>
    <item>
        <embed_code>ec113</embed_code>
        <name>lbl name 2</name>
        <full_name>full lbl name 2</full_name>
        <id>lbl2</id>
        <parent_id>parent_id_2</parent_id>
    </item>
    <item>
        <embed_code>ec113</embed_code>
        <name>lbl name 3</name>
        <full_name>full lbl name 3</full_name>
        <id>lbl3</id>
        <parent_id>parent_id_3</parent_id>
    </item>
</labels>

路径root / items / item将包含embed_code标记。并且在相同的路径中它可能具有标签节点或者可能没有标签。标签可能包含一个或多个项目。

转换规则如下: 1)需要获得标签及其子女 2)删除所有属性 3)将embed_code节点带入每个标签/项目节点

到目前为止,我的代码如下:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:a="item">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />

    <xsl:template match="/">
        <labels>
            <xsl:for-each select="root/items/item">
            <xsl:variable name="eCode" select="embed_code"/>
            <xsl:for-each select="labels/*">
            <item>
                <embed_code>
                    <xsl:value-of select="$eCode"/>
                </embed_code>

                <xsl:for-each select="root/items/item/labels/item/*">

                </xsl:for-each>
            </item>
            </xsl:for-each>
            </xsl:for-each>
        </labels>
    </xsl:template>

    <xsl:template match="@*" />
    </xsl:stylesheet>

无法带标签/项目的子节点。请帮助我。

由于

1 个答案:

答案 0 :(得分:0)

您无法访问标签/项目的子节点,因为您在

中使用了错误的路径
<xsl:for-each select="root/items/item/labels/item/*">

</xsl:for-each>

任何root下都没有<item>。看起来你试图使用绝对路径,这也是错误的。

请改用相对路径。 *足以获取所有子元素,因为<xsl:for-each>已将您的上下文节点移动到相关的<item>。比较:

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

    <xsl:template match="/">
        <labels>
            <xsl:for-each select="root/items/item/labels/item">
                <item>
                    <embed_code>
                        <xsl:value-of select="../../embed_code"/>
                    </embed_code>

                    <xsl:for-each select="*">
                        <xsl:copy>
                            <xsl:value-of select="." />
                        </xsl:copy>
                    </xsl:for-each>
                </item>
            </xsl:for-each>
        </labels>
    </xsl:template>

</xsl:stylesheet>

注释

  • 像你一样嵌套<xsl:for-each>并不是必需的,一个单独的 - 每个都做同样的事情
  • <xsl:copy>将当前节点复制到输出,如果要保留节点名称,可以使用它

输入结果如上:

<labels xmlns:a="item">
   <item>
      <embed_code>ec112</embed_code>
      <name>lbl name 1</name>
      <full_name>full lbl name 1</full_name>
      <id>lbl1</id>
      <parent_id>parent_id_1</parent_id>
   </item>
   <item>
      <embed_code>ec113</embed_code>
      <name>lbl name 2</name>
      <full_name>full lbl name 2</full_name>
      <id>lbl2</id>
      <parent_id>parent_id_2</parent_id>
   </item>
   <item>
      <embed_code>ec113</embed_code>
      <name>lbl name 3</name>
      <full_name>full lbl name 3</full_name>
      <id>lbl3</id>
      <parent_id>parent_id_3</parent_id>
   </item>
</labels>