XSLT转换:删除兄弟姐妹和父母,保留XML信息,添加新的父母和兄弟姐妹

时间:2015-07-14 20:38:10

标签: xml xslt xpath transformation

我有一个传入的XML文件,其中包含大量数据。我想使用XSLT来删除不需要的数据并添加新元素:

**<?xml version="1.0" encoding="UTF-8"?>
 <root>
  <child></child>
  <kid id="2">
    <name>abc</name>
    <age>15</age>
  </kid>
  <mykid></mykid>
 </root>**

我想把它转换成这个(删除了父母和兄弟姐妹并用新的父母包裹它):

 **<?xml version="1.0" encoding="UTF-8"?>
 <kids>
    <kid id="2">
        <name>abc</name>
        <age>15</age>
    </kid>
 </kids>**

以下是要求:

  1. 删除Kid元素的所有兄弟姐妹和父母。
  2. 保留Kid元素的所有细节,包括属性和嵌套元素。
  3. 添加新的父级。
  4. 我真的很感激,如果有人能写出我可以用来转换我的xml的XSLT文件的骨架吗?如果我错过任何事情,请告诉我。还有一件我想补充的内容,我不知道要移除的父母或兄弟姐妹的细节。我只知道感兴趣的元素和新的父母和兄弟姐妹。

1 个答案:

答案 0 :(得分:3)

首先,阅读XSLT Identity Transform,它可用于按原样复制现有元素和节点。

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

使用这意味着您可以直接满足要求2,并且只需要担心编写模板以涵盖要求1和3。

如果您将需求1编写为“删除kid元素的所有兄弟”,那会更好。然后,执行此操作的模板看起来像这样

<xsl:template match="*[kid]/*[not(self::kid)]" />

因此,*[kid]匹配kid元素的父级,然后/*[not(self::kid)]匹配子元素,kid本身除外。模板为空,因此元素被删除(或者更确切地说,它不会被复制到输出中)。

然后,可以将要求3视为“将kid元素的父项替换为kids”。执行此操作的模板如下:

<xsl:template match="*[kid]">
    <kids>
        <xsl:apply-templates select="@*|node()"/>
    </kids>
</xsl:template>

就是这样!试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:template match="*[kid]">
        <kids>
            <xsl:apply-templates select="@*|node()"/>
        </kids>
    </xsl:template>

    <xsl:template match="*[kid]/*[not(self::kid)]" />

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