应用XSLT合并两个XML文件,并在没有密钥匹配时复制节点

时间:2015-08-11 18:31:55

标签: java xml xslt xslt-1.0

我是XML和XSLT的新手。我想要做的是在两个文件中合并两个XML文件,对于我的案例id。当存在密钥匹配时,我复制节点的内容,对于我的情况,所有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更新此信息。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

  

我想要实现的是当没有关键匹配时   第二个档案。将整个缺失的父节点复制到第一个文件,即   是人数据。

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

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