如何使用XSLT1.0合并两个xml文件

问题描述 投票:0回答:1

我试图使用XSLT1.0合并两个xml文件。我试图合并FileOne和Filetwo合并到一个新的XML文件。结果xml应该包含来自文件2的一个元素,该元素基于来自measurement标签的值。任何帮助将不胜感激

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>PGW0002</measurement>
        </measurements>
        <measPeriods>
            <period day="0" duration="0" hour="0" interval="60" minutes="0"/>
        </measPeriods>
    </Item>
</Schedule>

Filetwo.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="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}"/>

仍然不合适

xml xslt
1个回答
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>

下面的输出显示periodPGW0001已被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>
© www.soinside.com 2019 - 2024. All rights reserved.