【问题标题】:Apply XSLT to merge two XML files and copy a node when there is no key match应用 XSLT 合并两个 XML 文件并在没有键匹配时复制一个节点
【发布时间】:2015-11-04 03:06:34
【问题描述】:

我是 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 更新此信息。

感谢您的帮助。

【问题讨论】:

    标签: java xml xslt xslt-1.0


    【解决方案1】:

    我想要实现的是,当 第二个文件。将整个丢失的父节点复制到第一个文件,该文件 是个人数据。

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

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

    【讨论】:

    • 感谢您对此的指导。
    猜你喜欢
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    相关资源
    最近更新 更多