应用XSLT合并两个XML个文件,在没有键匹配的情况下复制一个节点

Apply XSLT to merge two XML files and copy a node when there is no key match

我是 XML 和 XSLT 的新手。对于我的案例 id,我想要做的是合并两个 XML 文件,两个文件中的密钥匹配。当存在键匹配时,我复制节点的内容,对于我的情况,所有 appointment 都有效。我想要实现的是,当第二个文件中没有密钥匹配时。将整个缺失的父节点复制到第一个文件,即person-data。我应用 XSLT 的方式能够复制我的第一个文件中的节点,但不能将无键匹配 person-data 复制到合并文件中。我正在使用 XSLT 版本 1.0

这是我的 file1.xml:

<?xml version='1.0' encoding='UTF-8'?>
<people-appointment-data>
<person-data>        
    <id>12345</id>
    <first-name>John</first-name>
    <last-name>Hewitt</last-name>       
    <appointments>
      <appointment>
        <code>1</code>
        <pass>1</pass>
        <states>
            <state>IL</state>
            <state>IN</state>
        </states>
     </appointment>
      <appointment>
        <code>2</code>
        <pass>2</pass>
        <states>
            <state>NV</state>
            <state>CA</state>
        </states>
     </appointment>
</appointments>
</person-data>
<person-data>        
<id>67890</id>
<first-name>Mike</first-name>
<last-name>Hewitt</last-name>       
<appointments>
    <appointment>
        <code>5</code>
        <pass>5</pass>
        <states>
            <state>AK</state>
            <state>MA</state>
        </states>
    </appointment>
</appointments>
</person-data>
<person-data>        
<id>678678</id>
<first-name>Mike</first-name>
<last-name>Hewitt</last-name>       
<appointments>
    <appointment>
        <code>15</code>
        <pass>15</pass>
        <states>
            <state>AK</state>
            <state>MA</state>
        </states>
    </appointment>
</appointments>
</person-data>
<person-data>        
<id>679679</id>
<first-name>Mike</first-name>
<last-name>Hewitt</last-name>       
<appointments>
    <appointment>
        <code>20</code>
        <pass>20</pass>
        <states>
            <state>AK</state>
            <state>MA</state>
        </states>
    </appointment>
</appointments>
</person-data>
</people-appointment-data>

这是我的 file2.xml:

<?xml version='1.0' encoding='UTF-8'?>
<people-appointment-data>
<person-data>        
    <id>12345</id>
    <first-name>John</first-name>  
    <last-name>Hewitt</last-name>     
    <appointments>
      <appointment>
        <code>3</code>
        <pass>3</pass>
        <states>
            <state>IL</state>
            <state>IN</state>
        </states>
     </appointment>
      <appointment>
        <code>4</code>
        <pass>4</pass>
        <states>
            <state>NV</state>
            <state>CA</state>
        </states>
     </appointment>
</appointments>
</person-data>
<person-data>        
<id>67890</id>
<first-name>Mike</first-name>    
<last-name>Hewitt</last-name>   
<appointments>
    <appointment>
        <code>6</code>
        <pass>6</pass>
        <states>
            <state>AK</state>
            <state>MA</state>
        </states>
    </appointment>
</appointments>
</person-data>
<person-data>        
<id>141414</id>
<first-name>Mike</first-name>    
<last-name>Hewitt</last-name>   
<appointments>
    <appointment>
        <code>25</code>
        <pass>25</pass>
        <states>
            <state>AK</state>
            <state>MA</state>
        </states>
    </appointment>
</appointments>
</person-data>
<person-data>        
<id>151515</id>
<first-name>Mike</first-name>    
<last-name>Hewitt</last-name>   
<appointments>
    <appointment>
        <code>30</code>
        <pass>30</pass>
        <states>
            <state>AK</state>
            <state>MA</state>
        </states>
    </appointment>
</appointments>
</person-data>
</people-appointment-data>

这是我的 XSLT:

<?xml version="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:strip-space elements="*"/>

<xsl:param name="lookup-document" select="document('file2.xml')"/>
<xsl:key name="pdata" match="person-data" use="id" />

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

<xsl:template match="appointments">
    <xsl:variable name="id" select="../id" />
    <xsl:copy>
        <xsl:for-each select="$lookup-document">
            <xsl:apply-templates select="key('pdata', $id)/appointments/appointment"/>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

这就是我得到的结果,它缺少 file2.xml:

中的无关键匹配节点
<?xml version="1.0" encoding="UTF-8"?>
<people-appointment-data>
<person-data>
    <id>12345</id>
    <first-name>John</first-name>
    <last-name>Hewitt</last-name>
    <appointments>
        <appointment>
            <code>1</code>
            <pass>1</pass>
            <states>
                <state>IL</state>
                <state>IN</state>
            </states>
        </appointment>
        <appointment>
            <code>2</code>
            <pass>2</pass>
            <states>
                <state>NV</state>
                <state>CA</state>
            </states>
        </appointment>
        <appointment>
            <code>3</code>
            <pass>3</pass>
            <states>
                <state>IL</state>
                <state>IN</state>
            </states>
        </appointment>
        <appointment>
            <code>4</code>
            <pass>4</pass>
            <states>
                <state>NV</state>
                <state>CA</state>
            </states>
        </appointment>
    </appointments>
</person-data>
<person-data>
    <id>67890</id>
    <first-name>Mike</first-name>
    <last-name>Hewitt</last-name>
    <appointments>
        <appointment>
            <code>5</code>
            <pass>5</pass>
            <states>
                <state>AK</state>
                <state>MA</state>
            </states>
        </appointment>
        <appointment>
            <code>6</code>
            <pass>6</pass>
            <states>
                <state>AK</state>
                <state>MA</state>
            </states>
        </appointment>
    </appointments>
</person-data>
<person-data>
    <id>678678</id>
    <first-name>Mike</first-name>
    <last-name>Hewitt</last-name>
    <appointments>
        <appointment>
            <code>15</code>
            <pass>15</pass>
            <states>
                <state>AK</state>
                <state>MA</state>
            </states>
        </appointment>
    </appointments>
</person-data>
<person-data>
    <id>679679</id>
    <first-name>Mike</first-name>
    <last-name>Hewitt</last-name>
    <appointments>
        <appointment>
            <code>20</code>
            <pass>20</pass>
            <states>
                <state>AK</state>
                <state>MA</state>
            </states>
        </appointment>
    </appointments>
</person-data>
</people-appointment-data>

这就是我真正想要的合并结果:

<?xml version="1.0" encoding="UTF-8"?>
<people-appointment-data>
<person-data>
    <id>12345</id>
    <first-name>John</first-name>
    <last-name>Hewitt</last-name>
    <appointments>
        <appointment>
            <code>1</code>
            <pass>1</pass>
            <states>
                <state>IL</state>
                <state>IN</state>
            </states>
        </appointment>
        <appointment>
            <code>2</code>
            <pass>2</pass>
            <states>
                <state>NV</state>
                <state>CA</state>
            </states>
        </appointment>
        <appointment>
            <code>3</code>
            <pass>3</pass>
            <states>
                <state>IL</state>
                <state>IN</state>
            </states>
        </appointment>
        <appointment>
            <code>4</code>
            <pass>4</pass>
            <states>
                <state>NV</state>
                <state>CA</state>
            </states>
        </appointment>
    </appointments>
</person-data>
<person-data>
    <id>67890</id>
    <first-name>Mike</first-name>
    <last-name>Hewitt</last-name>
    <appointments>
        <appointment>
            <code>5</code>
            <pass>5</pass>
            <states>
                <state>AK</state>
                <state>MA</state>
            </states>
        </appointment>
        <appointment>
            <code>6</code>
            <pass>6</pass>
            <states>
                <state>AK</state>
                <state>MA</state>
            </states>
        </appointment>
    </appointments>
</person-data>
<person-data>
    <id>678678</id>
    <first-name>Mike</first-name>
    <last-name>Hewitt</last-name>
    <appointments>
        <appointment>
            <code>15</code>
            <pass>15</pass>
            <states>
                <state>AK</state>
                <state>MA</state>
            </states>
        </appointment>
    </appointments>
</person-data>
<person-data>
    <id>679679</id>
    <first-name>Mike</first-name>
    <last-name>Hewitt</last-name>
    <appointments>
        <appointment>
            <code>20</code>
            <pass>20</pass>
            <states>
                <state>AK</state>
                <state>MA</state>
            </states>
        </appointment>
    </appointments>
</person-data>
<person-data>        
<id>141414</id>
<first-name>Mike</first-name>    
<last-name>Hewitt</last-name>   
<appointments>
    <appointment>
        <code>25</code>
        <pass>25</pass>
        <states>
            <state>AK</state>
            <state>MA</state>
        </states>
    </appointment>
</appointments>
</person-data>
<person-data>        
<id>151515</id>
<first-name>Mike</first-name>    
<last-name>Hewitt</last-name>   
<appointments>
    <appointment>
        <code>30</code>
        <pass>30</pass>
        <states>
            <state>AK</state>
            <state>MA</state>
        </states>
    </appointment>
</appointments>
</person-data>
</people-appointment-data>

谁能指导我如何使用此 XSLT 更新此信息。

感谢您的帮助。

What I want to achieve is that when there is no key match in the second file. Copy the entire missing parent node to first file, which is the person-data.

尝试将以下模板添加到您的样式表中:

<xsl:template match="/people-appointment-data">
    <xsl:variable name="ids" select="person-data/id" />
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <xsl:copy-of select="$lookup-document/people-appointment-data/person-data[not(id=$ids)]"/>
    </xsl:copy>
</xsl:template>