如何使用XSLT

时间:2016-08-10 04:41:23

标签: xml xslt xslt-1.0

我正在尝试使用XSL文件在特定位置移动XML Attribute的特定元素。

假设我有XML

<all>
    <one>Something 1</one>
    <check>
        <present>
            <target> Hello </target>
            <abc> ABC </abc>
        </present>
        <absent> 
            <target> Hi </target>
            <pqr> PQR </pqr>
        </absent>
    </check>
    <action>
        <perform>
            <one>One</one>
            <two>Two</two>
        </perform>
    </action>
</all>

我想输出如下:

<all>
    <one>Something 1</one>
    <check>
        <present>
                     <abc> ABC </abc>
        </present>
        <absent> 
            <target> Hi </target>
            <pqr> PQR </pqr>
        </absent>
    </check>
    <action>
        <perform>
            <one>One</one>
            <two>Two</two>
            <target> Hello </target>
        </perform>
    </action>
</all>

为此,我写了

       <xsl:template match= "@*|node()" >
    <xsl:copy>
        <xsl:apply-templates select= "@*|node()" />
    </xsl:copy>
</xsl:template >
 <xsl:template match= "action" >
        <xsl:copy>
            <xsl:apply-templates select= "@*|node()" />
            <xsl:apply-templates select= "../check/present/target" mode= "move" />
        </xsl:copy>
    </xsl:template >
<xsl:template match="target" mode="move">
     <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
</xsl:template>

<target>Hello</target>移至<action>下方,但我希望它移到<perform>内的<action>

1 个答案:

答案 0 :(得分:0)

如果您想将target节点放在perform下,只需将模板匹配更改为匹配perform而不是action

<xsl:template match="action/perform">

甚至这个(如果perform只能在action下)

<xsl:template match="perform">

此外,由于您实际上没有移动节点,而是添加新节点并删除现有节点,因此您还需要一个模板来忽略当前的target节点

<xsl:template match="present/target" />

试试这个XSLT。请注意我如何将标识模板设置为命名模板以避免某些代码重复。

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

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

    <xsl:template match="present/target" />

    <xsl:template match="action/perform">
        <xsl:copy>
            <xsl:apply-templates select= "@*|node()" />
            <xsl:apply-templates select= "../../check/present/target" mode="move" />
        </xsl:copy>
    </xsl:template >

    <xsl:template match="target" mode="move">
        <xsl:call-template name="identity" />
    </xsl:template>
</xsl:stylesheet>

当然,如果您不打算修改target元素,则可以使用xsl:copy-of

试试这个

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

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

    <xsl:template match="present/target" />

    <xsl:template match="perform">
        <xsl:copy>
            <xsl:apply-templates select= "@*|node()" />
            <xsl:copy-of select= "../../check/present/target" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>