使用XSLT进行简单的XML重构

时间:2013-02-21 10:24:41

标签: xml xslt

我是XSLT的新手,我正在努力实现一个相当简单的重组。我有一个代表一个人的xml文档(用于说明目的)。我有很多元素。从中我想要将first_namelast_name(以及其他关键字)提取到新的full_name元素中。我见过问题here。 “renameWrapped”方法有效。但是它不够通用,因为我无法保证输入文档中元素的排序。

我有以下XML:

<?xml version="1.0" encoding="utf-8"?>
<myname:Person xmlns:myname="http://www.myname.co.uk/def">
    <myname:attr1>some value</myname:attr1>
    <myname:first_name>john</myname:first_name>
    <myname:last_name>smith</myname:last_name>
    <myname:attr2>some value</myname:attr2>
    <!-- other person stuff -->
</myname:Person>

这由以下xsl转换:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:myname="http://www.myname.co.uk/def">
    <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="myname:Person">
        <myname:Person>
            <xsl:copy>
                <xsl:apply-templates select="@*|node()[local-name() != 'first_name' and local-name() != 'Person' and local-name() != 'last_name']"/>
            </xsl:copy>
            <myname:FullName>
                <xsl:apply-templates select="myname:first_name | myname:last_name"/>
            </myname:FullName>
        </myname:Person>
    </xsl:template>

</xsl:stylesheet>

然而,这给了我以下输出myname:Person被复制:

<?xml version="1.0" encoding="UTF-8"?>
<myname:Person xmlns:myname="http://www.myname.co.uk/def">
    <myname:Person>
        <myname:attr1>some value</myname:attr1>
        <myname:attr2>some value</myname:attr2>
    </myname:Person>
    <myname:FullName>
        <myname:first_name>john</myname:first_name>
        <myname:last_name>smith</myname:last_name>
    </myname:FullName>
</myname:Person>

我做错了什么?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

其中一个<myname:Person>元素来自模板中的文字结果元素,另一个来自<xsl:copy>。如果你想要

<?xml version="1.0" encoding="UTF-8"?>
<myname:Person xmlns:myname="http://www.myname.co.uk/def">
    <myname:attr1>some value</myname:attr1>
    <myname:attr2>some value</myname:attr2>
    <myname:FullName>
        <myname:first_name>john</myname:first_name>
        <myname:last_name>smith</myname:last_name>
    </myname:FullName>
</myname:Person>

然后简单地省略<xsl:copy>,即

<xsl:template match="myname:Person">
    <myname:Person>
        <xsl:apply-templates select="@*|node()[local-name() != 'first_name' and local-name() != 'Person' and local-name() != 'last_name']"/>
        <myname:FullName>
            <xsl:apply-templates select="myname:first_name | myname:last_name"/>
        </myname:FullName>
    </myname:Person>
</xsl:template>

或者忽略明确的<myname:Person>

<xsl:template match="myname:Person">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()[local-name() != 'first_name' and local-name() != 'Person' and local-name() != 'last_name']"/>
        <myname:FullName>
            <xsl:apply-templates select="myname:first_name | myname:last_name"/>
        </myname:FullName>
    </xsl:copy>
</xsl:template>