我正在尝试使用XSLT1.0合并两个xml文件。我正在尝试将FileOne和Filetwo合并以合并到新的xml文件。根据测量标签的值,生成的xml应包含文件2中的一个元素。任何帮助将不胜感激
<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
如果<measPeriods>
中的值匹配,我的预期输出应具有Fileone.xml
中的<measurements>/<measurement>
标签
编辑了我的解决方案
<?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}"/>
仍然不正确
答案 0 :(得分:0)
从输入XML来看,Fileone.xml
似乎具有Filetwo.xml
的记录的子集。一种更简单的方法是编写XSL并将其应用于Filetwo.xml
(因为它具有所有记录,并且我们只需要替换很少的记录),然后使用Fileone.xml
函数访问document()
。>
对于<measurement>
的匹配值,可以使用<xsl:choose></xsl:choose>
从period
复制Fileone.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
的{{1}}已被PGW0001
中的相应节点替换。
Fileone.xml