我是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更新此信息。
感谢您的帮助。
答案 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>