【发布时间】: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 更新此信息。
感谢您的帮助。
【问题讨论】: