Xml XSL转换-合并元素

Xml XSL转换-合并元素,xml,xslt,review,Xml,Xslt,Review,我正在尝试合并2个xml文件(作为代码中的字符串) 而且。。。但这似乎有点过分了 您认为有更好的解决方案吗?看起来您试图做的是合并AMA和外部的子项 您几乎拥有了它,但是您需要移动根目录,删除xsl:for each,并更新第二个xsl:copy of中的select。(在我的示例中,我将固定路径移动到了的第一个xsl:copy。) 像这样的。。。(假设XSLT2.0,因为XPath中的(英里数)) XSLT2.0 <xsl:stylesheet version="2.0" xmlns:

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


而且。。。但这似乎有点过分了


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

看起来您试图做的是合并
AMA
外部
子项

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

像这样的。。。(假设XSLT2.0,因为XPath中的
(英里数)

XSLT2.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>


如果需要切换到XSLT 1.0,请将
(里程|点)
更改为
*[self::Miles或self::Points]

您能详细说明一下吗?什么是“硬编码配置文件节点”?我真的不知道你在问什么。您已经向我们展示了一个输入文档,而不是您所说的两个,并且您还没有真正向我们解释您希望合并做什么。我同意@KirillPolishchuk的观点,即不清楚“硬编码概要文件节点”是什么意思——你想做什么,而当前的方法无法做到?另外,请注意样式表的格式不正确——根元素嵌套不正确,没有根节点模板来启动匹配过程,但由于它有一个模板,所以它不是拉式样式表。停止并定义问题。是的,有一个更好的解决方案:使用键查找外部值。不,它与“避免”硬编码“配置文件节点”无关-您请求的这一部分不清楚,正如其他人已经指出的。-还要注意,
没有任何作用。@keshlam我正在合并两个xml文件,将它们包装在一个假容器根中。@michael.hor257k关于密钥查找(在链接中提到)。。。为什么应该更好?如果英里和点位于纵断面的一个内部元素中,并且我希望它们保持在相同的深度,该怎么办?
<?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>
<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>