XSL转换 - 合并元素

时间:2014-09-30 23:41:36

标签: xml xslt review

我正在尝试合并2个xml文件(作为代码中的字符串)。

<Root>
    <AMA>
        <Profile>
            <UniqueID id="3"/>
            <Name type="UN">TOTO</Name>
            <Address>AAA</Address>
        </Profile>
        <Profile>
            <UniqueID id="4"/>
            <Name>TOTA</Name>
            <Address>BBB</Address>
        </Profile>
        <Profile>
            <UniqueID id="5"/>
            <Name>TOTQ</Name>
        </Profile>
        <Profile>
            <UniqueID id="6"/>
            <Name>TOTG</Name>
        </Profile>
        <Profile>
            <UniqueID id="7"/>
            <Name>TOTB</Name>
            <Address>CCC</Address>
        </Profile>
    </AMA>
    <External>
        <Profile>
            <UniqueID id="3"/>
            <Miles>5</Miles>
        </Profile>
        <Profile>
            <UniqueID id="4"/>
            <Miles>4</Miles>
<Points>22222</Points>
        </Profile>
        <Profile>
            <UniqueID id="5"/>
            <Miles>3</Miles>
        </Profile>
        <Profile>
            <UniqueID id="6"/>
            <Miles>2</Miles>
        </Profile>
        <Profile>
            <UniqueID id="7"/>
            <Miles>1</Miles>
        </Profile>
    </External>
</Root>

我想获得

<?xml version="1.0" encoding="ISO-8859-1"?>
<Root>
    <Profile>
        <UniqueID id="3"/>
        <Name type="UN">TOTO</Name>
        <Address>AAA</Address>
        <Miles>5</Miles>
    </Profile>
    <Profile>
        <UniqueID id="4"/>
        <Name>TOTA</Name>
        <Address>BBB</Address>
        <Miles>4</Miles>
        <Points>22222</Points>
    </Profile>
    <Profile>
        <UniqueID id="5"/>
        <Name>TOTQ</Name>
        <Miles>3</Miles>
    </Profile>
    <Profile>
        <UniqueID id="6"/>
        <Name>TOTG</Name>
        <Miles>2</Miles>
    </Profile>
    <Profile>
        <UniqueID id="7"/>
        <Name>TOTB</Name>
        <Address>CCC</Address>
        <Miles>1</Miles>
    </Profile>
</Root>

我设法写了类似的东西:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes" />
    <Root>
    <xsl:template match="/Root/AMA/Profile">
        <Profile>
            <xsl:for-each select=".">
                <xsl:copy-of select="@*|node()"/>
                <xsl:copy-of select="/Root/External/Profile/UniqueID[@id=current()/UniqueID/@id]/../(Miles|Points)"/>
            </xsl:for-each>
        </Profile>
    </xsl:template>
    <xsl:template match="/root/External"/>
</xsl:transform>
    </Root>

如何避免“硬编码”Profile节点?

通过“硬编码”,我的意思是“不要将配置文件元素标签打开和关闭我的手在XML转换中,而只是从原始节点复制配置文件节点。

似乎存在另一种方法,使用XSLT Lookup Tableshere ......但似乎有点矫枉过正。

您认为有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

您尝试执行的操作似乎是合并ProfileAMA的{​​{1}}子项。

您几乎拥有它,但您需要移动External,移除Root并更新第二个xsl:for-each中的select。 (我将固定路径移到了我示例中的第一个xsl:copy-of。)

像这样......(假设你的XPath中有xsl:copy-of的XSLT 2.0)

XSLT 2.0

(Miles|Points)

如果您需要切换到XSLT 1.0,请将<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <!--This will handle <Root/>--> <xsl:template match="/*"> <xsl:copy> <xsl:apply-templates select="@*|AMA/Profile"/> </xsl:copy> </xsl:template> <xsl:template match="/Root/AMA/Profile"> <Profile> <xsl:copy-of select="@*|node()| /*/External/Profile[UniqueID/@id=current()/UniqueID/@id]/(Miles|Points)"/> </Profile> </xsl:template> </xsl:stylesheet> 更改为(Miles|Points)