[英]How to merge two xml files using XSLT1.0
I am trying to merge two xml files using XSLT1.0. 我试图使用XSLT1.0合并两个xml文件。 I am trying to merge FileOne and Filetwo to merge to a new xml file.
我试图合并FileOne和Filetwo合并到一个新的XML文件。 The resultant xml should contain one element from file two based on the value from measurement tag.
结果xml应该包含来自文件2的一个元素,该元素基于来自measurement标签的值。 Any help would be greatly appreciated
任何帮助将不胜感激
<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>
My expected output is 我的预期产量是
<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>
please note that expected output 请注意预期的输出
<measPeriods>
<period day="0" duration="0" hour="0" interval="15" minutes="0"/>
</measPeriods>
I tried the following code 我尝试了以下代码
<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
my expected output should have the <measPeriods>
tag from Fileone.xml
if the value in <measurements>/<measurement>
matches 如果
<measurements>/<measurement>
中的<measurements>/<measurement>
匹配,我的预期输出应该具有来自Fileone.xml
的<measPeriods>
标记
edited my solution to 编辑了我的解决方案
<?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>
now i am getting Item tag properly but 现在我正在获得Item标签但是
<period day="{$day}" duration="{$duration}" hour="{$hour}" interval="{$interval}" minutes="{$minutes}"/>
is still not proper 仍然不合适
From the input XMLs, it looks like Fileone.xml
has a subset of records from the Filetwo.xml
. 从输入个XML,它看起来像
Fileone.xml
具有从记录的子集Filetwo.xml
。 An easier approach will be write the XSL and apply it on Filetwo.xml
(since it has all the records and we have to replace only few) and access Fileone.xml
using the document()
function. 一种更简单的方法是编写XSL并将其应用于
Filetwo.xml
(因为它具有所有记录,我们只需要替换少数记录)并使用document()
函数访问Fileone.xml
。
For the matching value of <measurement>
, you can use the <xsl:choose></xsl:choose>
to copy period
from Fileone.xml
and for the non-matching value, retain period
from Filetwo.xml
. 对于
<measurement>
的匹配值,可以使用<xsl:choose></xsl:choose>
从Fileone.xml
复制period
Fileone.xml
,对于不匹配的值,从Filetwo.xml
保留period
Filetwo.xml
。 Below is the <xsl:choose>
block. 下面是
<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>
Here current()
is used to access the correct node and its corresponding sibling's measurement
value. 这里
current()
用于访问正确的节点及其相应的兄弟measurement
值。
The complete XSLT is as below 完整的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>
The output below shows the period
for PGW0001
has been replaced with the corresponding node from Fileone.xml
. 下面输出显示
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.