繁体   English   中英

使用XSLT基于属性合并Xml元素

[英]Merge Xml elements based on attribute using XSLT

我想合并position元素,并在比较type属性后创建一个名为travel的新元素。 第一个type =“ from”必须与找到的第一个type =“ to”合并,其余应继续。

INPUT

<?xml version="1.0" encoding="UTF-8"?>
<JOB age="0" priority="N">
    <container ID="TSTU2345678" TP="4200"/>
    <container ID="TSTU3456789" TP="4200"/>
    <position refID="Y.Test:AA.01.01.1" name="AA0101.1" type="from"/>
    <position refID="Y.Test:AA.01.02.1" name="AA0102.1" type="from"/>
    <position refID="Y.Test:AA.02.02.1" name="AA0202.1" type="to"/>
    <position refID="Y.Test:AA.02.03.1" name="AA0203.1" type="to"/>
</JOB>

所需的输出

<JOB age="0" priority="N">
    <Travel FromrefID="Y.Test:AA.01.01.1" Fromname="AA0101.1" TorefID="Y.Test:AA.02.02.1" Toname="AA0202.1"/>
    <Travel FromrefID="Y.Test:AA.01.02.1" Fromname="AA0102.1" TorefID="Y.Test:AA.02.03.1" Toname="AA0203.1"/>
</JOB>

到目前为止我尝试过的。 它将所有To类型添加到from元素中。 我不确定如何选择第一个并将其标记为已使用。 另外,如何更改属性名称。 请帮忙。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="position" match="job/position" use="@type" />
    <xsl:template match="job">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/">
        <JOB>
            <xsl:apply-templates select="job/@*" />
            <xsl:for-each select="key('position','from')">
                <Travel>
                    <xsl:apply-templates select="@*" />

                    <xsl:for-each select="key('position','to')">
                        <To>
                            <xsl:apply-templates select="@*" />
                        </To>
                    </xsl:for-each>
                </Travel>

            </xsl:for-each>
        </JOB>
    </xsl:template>

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

</xsl:stylesheet>

谢谢。

我建议你这样看:

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:key name="to" match="position[@type='to']" use="count(preceding-sibling::position[@type='to'])" />

<xsl:template match="/JOB">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:for-each select="position[@type='from']">
            <xsl:variable name="to" select="key('to', position() - 1)" />
            <Travel FromrefID="{@refID}" Fromname="{@name}" TorefID="{$to/@refID}" Toname="{$to/@name}"/>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

注意,这里我们假设“ from”和“ to”位置的数目相等(或者至少“ from”位置的数目不少于“ to”位置的数目)。

替代XSLT 1.0解决方案

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

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|position[@type='from']"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="position[@type='from']">
        <xsl:variable name="fromPos" select="position()"/>
        <Travel FromRefId="{@refID}" Fromname="{@name}">
            <xsl:apply-templates select="position[@type='to'][position()=$fromPos]"/>
        </Travel>
    </xsl:template>

    <xsl:template match="position[@type='to']">
        <xsl:attribute name="TorefID">
            <xsl:value-of select="@refID"/>
        </xsl:attribute>
        <xsl:attribute name="Toname">
            <xsl:value-of select="@name"/>
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM