Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml XSLT合并两个文档中元素的属性_Xml_Xslt - Fatal编程技术网

Xml XSLT合并两个文档中元素的属性

Xml XSLT合并两个文档中元素的属性,xml,xslt,Xml,Xslt,我有两个需要合并的XML文档。每个元素都有一个已定义的ID。如果一个元素在两个文档中都是唯一的,则->将添加到结果中,否则->属性将合并 main.xml <main> <el id="1" attr1="value1" /> <el id="2" attr2="value2" default-attr="def" /> </main> <main> <el id="2" attr2="new value

我有两个需要合并的XML文档。每个元素都有一个已定义的ID。如果一个元素在两个文档中都是唯一的,则->将添加到结果中,否则->属性将合并

main.xml

<main>
    <el id="1" attr1="value1" />
    <el id="2" attr2="value2" default-attr="def" />
</main>
<main>
    <el id="2" attr2="new value2" new-attr="some value" />
    <el id="3" attr3="value3" />
</main>
<main>
    <el id="1" attr1="value1" />
    <el id="2" attr2="new value2" default-attr="def" new-attr="some value" />
    <el id="3" attr3="value3" />
</main>

snippet.xml

<main>
    <el id="1" attr1="value1" />
    <el id="2" attr2="value2" default-attr="def" />
</main>
<main>
    <el id="2" attr2="new value2" new-attr="some value" />
    <el id="3" attr3="value3" />
</main>
<main>
    <el id="1" attr1="value1" />
    <el id="2" attr2="new value2" default-attr="def" new-attr="some value" />
    <el id="3" attr3="value3" />
</main>

result.xml

<main>
    <el id="1" attr1="value1" />
    <el id="2" attr2="value2" default-attr="def" />
</main>
<main>
    <el id="2" attr2="new value2" new-attr="some value" />
    <el id="3" attr3="value3" />
</main>
<main>
    <el id="1" attr1="value1" />
    <el id="2" attr2="new value2" default-attr="def" new-attr="some value" />
    <el id="3" attr3="value3" />
</main>

el[@id=2]中的属性被合并,值被snippet.xml覆盖

我试过这个:

merge.xlst

<?xml version="1.0" encoding="UTF-8"?>
<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:param name="snippetDoc" select="document(snippet.xml)" />

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

    <xsl:template match="el">
        <xsl:copy>
            <!-- how to distinguish between @ids of two documents? -->
            <xsl:copy-of select="$snippetDoc/main/el/[@id = @id]/@*" />
            <xsl:apply-templates select="@*" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

但它需要能够区分两个文档中的相同属性。而且,这不会复制snippet.xml中的唯一元素


谢谢你的帮助

您要寻找的表达式是

 <xsl:copy-of select="$snippetDoc/main/el[@id=current()/@id]/@*" />
试试这个XSLT

<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:param name="snippetDoc" select="document('snippet.xml')" />

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

    <xsl:template match="el">
        <xsl:copy>
            <!-- how to distinguish between @ids of two documents? -->
            <xsl:apply-templates select="@*" />
            <xsl:copy-of select="$snippetDoc/main/el[@id=current()/@id]/@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="main">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:copy-of select="$snippetDoc/main/el[not(@id=current()/el/@id)]" />
        </xsl:copy>     
    </xsl:template>

</xsl:stylesheet>

请注意,
node()
实际上是
*| text()| comment()| processing-instruction()
的缩写,因此执行
node()| comment()
实际上是不必要的