使用XSLT更改XML根节点

时间:2016-02-04 11:35:56

标签: xml xslt

我是XSLT的新手。我想在其他子节点的条件下更改XML中的根节点。但要保持子节点始终相同。例如,我有以下XML:

   <Root1>
    ................
    ................

    <Root2>
    ................
    ................

        <AnimalOrPlant>
             <Type>A</Type>
              <Food1>Something</Food1>
              <Food2>Somthing11</Food2>
              <Name>ant</Name>
              <Color>Black</GIIN>
              <Waterconsumption>5lt</Waterconsumption>
        </AnimalOrPlant>  
    ................
    ................

    </Root2>
    ................
    ................
</Root1>

我喜欢将XML更改为:

<Root1>
    ................
    ................
    <Root2>
    ................
    ................
        <Animal>
             <Type>A</Type>
              <Food1>Something</Food1>
              <Food2>Somthing11</Food2>
              <Name>ant</Name>
              <Color>Black</Color>
              <Waterconsumption>5lt</Waterconsumption>
        </Animal>
     ................
    ................ 
    </Root2>
    ................
    ................
</Root1>

这意味着<type> = A上的依赖项,我已将节点<AnimalOrPlant>更改为<Animal>。如果是<Type> = P,我会将其更改为<Plant>。我已编写以下XSLT:

<xsl:template match="Root1">
 <xsl:choose>
    <xsl:when test="Root2/AnimalOrPlant/Type='A'">
        <Animal>
            <xsl:element name ="Type">
              <xsl:value-of select="Root2/AnimalOrPlant/Type"/>
            </xsl:element>
            <xsl:element name ="Food1">
              <xsl:value-of select="Root2/AnimalOrPlant/Food1"/>          
            </xsl:element>
            <xsl:element name ="Food2">
              <xsl:value-of select="Root2/AnimalOrPlant/Food2"/>
            </xsl:element>
            <xsl:element name ="Name">
              <xsl:value-of select="<xsl:value-of select="Root2/AnimalOrPlant/Name"/>
            </xsl:element>
            <xsl:element name ="Color">
              <xsl:value-of select="<xsl:value-of select="Root2/AnimalOrPlant/Color"/>
            </xsl:element>
            <xsl:element name ="Waterconsumption">
              <xsl:value-of select="<xsl:value-of select="Root2/AnimalOrPlant/Waterconsumption"/>
            </xsl:element>
        </Animal>
    </xsl:when>
    <xsl:when test="Root2/AnimalOrPlant/Type='P'">
        <Plant>
            <xsl:element name ="Type">
              <xsl:value-of select="Root2/AnimalOrPlant/Type"/>
            </xsl:element>
            <xsl:element name ="Food1">
              <xsl:value-of select="Root2/AnimalOrPlant/Food1"/>          
            </xsl:element>
            <xsl:element name ="Food2">
              <xsl:value-of select="Root2/AnimalOrPlant/Food2"/>
            </xsl:element>
            <xsl:element name ="Name">
              <xsl:value-of select="<xsl:value-of select="Root2/AnimalOrPlant/Name"/>
            </xsl:element>
            <xsl:element name ="Color">
              <xsl:value-of select="<xsl:value-of select="Root2/AnimalOrPlant/Color"/>
            </xsl:element>
            <xsl:element name ="Waterconsumption">
              <xsl:value-of select="<xsl:value-of select="Root2/AnimalOrPlant/Waterconsumption"/>
            </xsl:element>
        </Plant>
    </xsl:when>
</xsl:choose>   
</xsl:template>

我不想在每个<when>条件下重复子节点。因为会有几种不同的类型。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:0)

如果您了解XSLT identity template

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

这会复制XML中的所有现有节点,因此您只需担心要更改的节点。您只需编写模板以匹配这些模板。例如,要将带有AnimalOrPlant A的Type元素转换为Animal元素,请执行以下操作:

<xsl:template match="AnimalOrPlant[Type='A']">
    <Animal>
        <xsl:apply-templates select="@*|node()"/>
    </Animal>
</xsl:template>

试试这个XSLT

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

    <xsl:template match="AnimalOrPlant[Type='A']">
        <Animal>
            <xsl:apply-templates select="@*|node()"/>
        </Animal>
    </xsl:template>

    <xsl:template match="AnimalOrPlant[Type='P']">
        <Plant>
            <xsl:apply-templates select="@*|node()"/>
        </Plant>
    </xsl:template>

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

答案 1 :(得分:0)

我建议你这样试试:

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="*"/>

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

<xsl:template match="AnimalOrPlant">
    <xsl:variable name="name">
        <xsl:choose>
            <xsl:when test="Type='A'">Animal</xsl:when>
            <xsl:when test="Type='P'">Plant</xsl:when>
            <xsl:otherwise>Unknown</xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:element name="{$name}">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

注意:这与根节点或与根元素无关。