[英]How to merge two xml files using XSLT1.0
我试图使用XSLT1.0合并两个xml文件。 我试图合并FileOne和Filetwo合并到一个新的XML文件。 结果xml应该包含来自文件2的一个元素,该元素基于来自measurement标签的值。 任何帮助将不胜感激
<Schedule name="NE3S">
<Item scheduleId="1" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGW0001</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="15" minutes="0"/>
</measPeriods>
</Item>
<Item scheduleId="2" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGW0002</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="60" minutes="0"/>
</measPeriods>
</Item>
</Schedule>
<Schedule name="NE3S">
<Item scheduleId="1" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGW0001</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="60" minutes="0"/>
</measPeriods>
</Item>
<Item scheduleId="2" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGD0001</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="60" minutes="0"/>
</measPeriods>
</Item>
<Item scheduleId="3" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGW0002</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="60" minutes="0"/>
</measPeriods>
</Item>
</Schedule>
我的预期产量是
<Schedule name="NE3S">
<Item scheduleId="1" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGW0001</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="15" minutes="0"/>
</measPeriods>
</Item>
<Item scheduleId="2" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGD0001</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="60" minutes="0"/>
</measPeriods>
</Item>
<Item scheduleId="3" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGW0002</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="60" minutes="0"/>
</measPeriods>
</Item>
</Schedule>
请注意预期的输出
<measPeriods>
<period day="0" duration="0" hour="0" interval="15" minutes="0"/>
</measPeriods>
我尝试了以下代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="fileName" select="'/opt/Filetwo.xml'" />
<xsl:param name="updates" select="document($fileName)" />
<xsl:variable name="updateMeasurement" select="$updates/Schedule/Item" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Schedule">
<xsl:copy>
<xsl:apply-templates select="Item[not(measurements/measurement = $updateMeasurement/measurements/measurement)]" />
<xsl:apply-templates select="/Schedule/Item//measurements" />
<xsl:apply-templates select="$updates/Schedule/Item/measPeriods" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
xsltproc merge.xslt /opt/Fileone.xml > /opt/FileThree.xml
如果<measurements>/<measurement>
中的<measurements>/<measurement>
匹配,我的预期输出应该具有来自Fileone.xml
的<measPeriods>
标记
编辑了我的解决方案
<?xml version="1.0" encoding="UTF-8"?>
<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:variable name="addresses"
select="document('/opt/esymac/extras/esymacstarter/schedule/MJ.netact.xml_backup')"/>
<xsl:template match="/measSchedule">
<measSchedule name="NE3S">
<xsl:for-each select="scheduleItem">
<xsl:variable name="id" select="@scheduleId"/>
<xsl:variable name="startDate" select="@startDate"/>
<xsl:variable name="stopDate" select="@stopDate"/>
<xsl:variable name="day" select="measPeriods/period/@day"/>
<xsl:variable name="duration" select="measPeriods/period/@duration"/>
<xsl:variable name="hour" select="measPeriods/period/@hour"/>
<xsl:variable name="minutes" select="measPeriods/period/@minutes"/>
<xsl:variable name="interval"
select="$addresses/measSchedule/scheduleItem/measurements[$counterId =
@measurement]/measPeriods/@interval"/>
<Item scheduleId="{$id}" startDate="{$startDate}" stopDate="{$stopDate}">
<measurements>
<measurement><xsl:value-of select="measurements/measurement"/></measurement>
</measurements>
<measPeriods>
<period day="{$day}" duration="{$duration}" hour="{$hour}" interval="{$interval}" minutes="{$minutes}"/>
</measPeriods>
</Item>
</xsl:for-each>
</measSchedule>
</xsl:template>
</xsl:stylesheet>
现在我正在获得Item标签但是
<period day="{$day}" duration="{$duration}" hour="{$hour}" interval="{$interval}" minutes="{$minutes}"/>
仍然不合适
从输入个XML,它看起来像Fileone.xml
具有从记录的子集Filetwo.xml
。 一种更简单的方法是编写XSL并将其应用于Filetwo.xml
(因为它具有所有记录,我们只需要替换少数记录)并使用document()
函数访问Fileone.xml
。
对于<measurement>
的匹配值,可以使用<xsl:choose></xsl:choose>
从Fileone.xml
复制period
Fileone.xml
,对于不匹配的值,从Filetwo.xml
保留period
Filetwo.xml
。 下面是<xsl:choose>
块。
<xsl:choose>
<xsl:when test="$extSchedule/Item/measurements/measurement = current()/ancestor::Item/measurements/measurement">
<xsl:copy-of select="$extSchedule/Item[measurements/measurement = current()/ancestor::Item/measurements/measurement]/measPeriods/period" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="period" />
</xsl:otherwise>
</xsl:choose>
这里current()
用于访问正确的节点及其相应的兄弟measurement
值。
完整的XSLT如下
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:strip-space elements="*" />
<xsl:param name="fileName" select="document('Fileone.xml')" />
<xsl:variable name="extSchedule" select="$fileName/Schedule" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="measPeriods">
<xsl:copy>
<xsl:choose>
<xsl:when test="$extSchedule/Item/measurements/measurement = current()/ancestor::Item/measurements/measurement">
<xsl:copy-of select="$extSchedule/Item[measurements/measurement = current()/ancestor::Item/measurements/measurement]/measPeriods/period" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="period" />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
下面输出显示period
为PGW0001
已经被替换为从对应节点Fileone.xml
。
<Schedule name="NE3S">
<Item scheduleId="1" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGW0001</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="15" minutes="0" />
</measPeriods>
</Item>
<Item scheduleId="2" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGD0001</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="60" minutes="0" />
</measPeriods>
</Item>
<Item scheduleId="3" startDate="2013-01-01" stopDate="2037-12-31">
<measurements>
<measurement>PGW0002</measurement>
</measurements>
<measPeriods>
<period day="0" duration="0" hour="0" interval="60" minutes="0" />
</measPeriods>
</Item>
</Schedule>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.