Xml标签添加

时间:2018-04-06 08:47:01

标签: xslt-1.0

我有一个小的Xml,我需要将其转换为另一种xml格式。我想通过xslt1.0转换。

以下是我的输入Xml

<Members>
    <Member name="1" />
    <Member name="2" />
    <Member name="3" />
    <Member name="4" />
    <Member name="5" /> 
</Members>

上面的输出xml将是

<Members>
    <JoinMember>
        <Member name="1" />
        <JoinMember>
            <Member name="2" />
            <JoinMember>
                <Member name="3" />
                <JoinMember>
                    <Member name="4" />
                    <Member name="5" /> 
                </JoinMember>
            </JoinMember>
        </JoinMember>
    </JoinMember>
</Members>

这里的逻辑是最后两个成员必须包含在一个单独的标记中。

例如

成员5和成员4

<JoinMember>
    <Member name="4" />
    <Member name="5" /> 
</JoinMember>

对于会员3,会员4和会员5

输出应如下:

<JoinMember>
    <Member name="3" />
    <JoinMember>
        <Member name="4" />
        <Member name="5" /> 
    </JoinMember>
</JoinMember>

它还包含已成员4和成员4的组合成员。 5。

JoinMember只能包含一个组合。

像第一个成员一样必须重复。

我需要通过XSLT1.0来完成。

请帮我输出。

先谢谢。

2 个答案:

答案 0 :(得分:0)

我已经调整了http://www.dpawson.co.uk/xsl/sect2/flatfile.html#d5010e369中的样式表。

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

    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:key name="h2" match="Member[@name='2']"
        use="generate-id(preceding-sibling::Member[@name='1'][1])"/>
    <xsl:key name="h3" match="Member[@name='3']"
        use="generate-id(preceding-sibling::Member[@name='2'][1])"/>
    <xsl:key name="h4" match="Member[@name='4']"
        use="generate-id(preceding-sibling::Member[@name='3'][1])"/>
    <xsl:key name="h5" match="Member[@name='5']"
        use="generate-id(preceding-sibling::Member[@name='4'][1])"/>

    <!--   Wendell Piez algorithm -->
    <xsl:template match="Members">
        <Members>
            <xsl:apply-templates select="Member[@name='1']" mode="h1"/>
        </Members>
    </xsl:template>

    <xsl:template match="Member[@name='1']" mode="h1">
        <JoinMember>
            <xsl:copy-of select="."/>
            <xsl:apply-templates select="key('h2',generate-id())" mode="h2"/>
        </JoinMember>
    </xsl:template>

    <xsl:template match="Member[@name='2']" mode="h2">
        <JoinMember>
            <xsl:copy-of select="."/>
            <xsl:apply-templates select="key('h3',generate-id())" mode="h3"/>
        </JoinMember>
    </xsl:template>

    <xsl:template match="Member[@name='3']" mode="h3">
        <JoinMember>
            <xsl:copy-of select="."/>
            <xsl:apply-templates select="key('h4',generate-id())" mode="h4"/>
        </JoinMember>
    </xsl:template>

    <xsl:template match="Member[@name='4']" mode="h4">
        <JoinMember>
            <xsl:copy-of select="."/>
            <xsl:apply-templates select="key('h5',generate-id())" mode="h5"/>
        </JoinMember>
    </xsl:template>

    <xsl:template match="Member[@name='5']" mode="h5">
        <xsl:copy-of select="."/>
    </xsl:template>

</xsl:stylesheet>

在行动here中查看。

答案 1 :(得分:0)

我使用递归模板循环遍历数字,最后有条件地放在自己节点中的最后一对。

<xsl:variable name="count"><xsl:value-of select="count(Members/*)"/></xsl:variable>

<xsl:template match="Members">
    <Members>
        <xsl:call-template name="recurse">
            <xsl:with-param name="memberNum" select="1"/>
        </xsl:call-template>
    </Members>
</xsl:template>

<xsl:template name="recurse">
    <xsl:param name="memberNum"/>

    <JoinMember>
        <xsl:if test="$memberNum &lt; ($count - 1)">
            <xsl:copy-of select="/Members/*[@name= $memberNum]"/>

            <xsl:call-template name="recurse">
                <xsl:with-param name="memberNum" select="$memberNum + 1"/>
            </xsl:call-template>
        </xsl:if>
        <xsl:if test = "$memberNum >= ($count - 1)">
            <xsl:copy-of select="/Members/*[@name = ($count - 1) or @name = $count]"/>
        </xsl:if>
    </JoinMember>
</xsl:template>

请在此处查看:http://xsltfiddle.liberty-development.net/pPqsHT7