在unix中使用XSLT合并2个xml文件

在unix中使用XSLT合并2个xml文件,xml,unix,xslt,merge,Xml,Unix,Xslt,Merge,我有2个XML文件,如下所示: File1.xml <?xml version="1.0" encoding="UTF-8" standalone="no"?> <Schedule name="myOffice"> <taskItem taskId="1" startDate="2013-01-01" stopDate="2037-12-31"> <measurements> <measurement>USD&l

我有2个XML文件,如下所示:

File1.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Schedule name="myOffice">
  <taskItem taskId="1" startDate="2013-01-01" stopDate="2037-12-31">
    <measurements>
      <measurement>USD</measurement>
    </measurements>
    <timings>
      <period day="0" duration="0" hour="0" interval="28" minutes="0"/>
    </timings>
  </taskItem>
  <taskItem taskId="2" startDate="2013-01-01" stopDate="2037-12-31">
    <measurements>
      <measurement>Rupee</measurement>
    </measurements>
    <timings>
      <period day="0" duration="0" hour="0" interval="15" minutes="0"/>
    </timings>
  </taskItem>
</Schedule>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Schedule name="myOffice">
  <taskItem taskId="1" startDate="2015-12-01" stopDate="2037-12-31">
    <measurements>
      <measurement>Rupee</measurement>
    </measurements>
    <timings>
      <period day="5" duration="10" hour="0" interval="20" minutes="0"/>
    </timings>
  </taskItem>
</Schedule>
我在unix中执行以下命令:

xsltproc xs.xslt file2.xml
我想你想做:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>

<xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<xsl:template match="timings">
    <xsl:variable name="match" select="document('file2.xml')/Schedule/taskItem[measurements/measurement=current()/../measurements/measurement]/timings"/>
    <xsl:choose>
        <xsl:when test="$match">
            <xsl:copy-of select="$match"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy-of select="."/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

并指定
file1.xml
作为要处理的文件。

根据我的理解,这是我的(详细)解决方案。我显式地更新每个属性/字段,以便您可以调整此解决方案以使其适应您的需要。taskItem中的taskId和startDate取自file1.xml。停止日期和时间取自file2.xml。必须使用file1.xml作为参数调用此XSLT表

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" omit-xml-declaration="yes"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  <!-- For all taskItem in file1.xml -->
  <xsl:template match="taskItem">
    <!-- Get all taskItems from file2.xml -->
    <xsl:variable name="tiother" select="document('file2.xml')/Schedule/taskItem" />
    <!-- Get measurement text from current and other taskItems (from file1.xml and file2.xml) -->
    <xsl:variable name="namethis" select="./measurements/measurement/text()" />
    <xsl:variable name="nameother" select="$tiother/measurements/measurement/text()" />
    <xsl:choose>
      <!-- if the measurement texts are the same -->
      <xsl:when test="$namethis = $nameother">
        <!-- Yes ? create a new taskItem updated -->
        <xsl:element name="taskItem">
          <!-- Get taskId from the current task item (the one in file1.xml) -->
          <xsl:attribute name="taskId"><xsl:value-of select="./@taskId"/></xsl:attribute>
          <!-- Get startDate from the current task item (the one in file1.xml) -->
          <xsl:attribute name="startDate"><xsl:value-of select="./@startDate"/></xsl:attribute>
          <!-- Get stopDate from the other task item (the one in file2.xml) -->
          <xsl:attribute name="stopDate"><xsl:value-of select="$tiother/@stopDate"/></xsl:attribute>
          <!-- Get the measurements from the current task item (the one in file1.xml) -->
          <xsl:copy-of select="./measurements"/>
          <!-- Get the timings from the other task item (the one in file2.xml) -->
          <xsl:copy-of select="$tiother/timings"/>
        </xsl:element>
      </xsl:when>
      <xsl:otherwise>
        <!-- No ? just copy the current taskItem -->
        <xsl:copy-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>


谢谢你的回答,但是我得到的输出没有标题…我如何直接通过XSLT包含…这一个…我以为你不想要XML声明,因为你的XSLT显式地省略了它,我复制了它。如果确实需要,请从
xsl:output
指令中删除
ommit-xml declaration=“yes”
属性(或将其值更改为
“yes”
)。此项仅添加
,但如果我需要完整的标题
,那么我应该如何处理
xsl:output
指令
xsltproc xs.xslt file2.xml
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>

<xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<xsl:template match="timings">
    <xsl:variable name="match" select="document('file2.xml')/Schedule/taskItem[measurements/measurement=current()/../measurements/measurement]/timings"/>
    <xsl:choose>
        <xsl:when test="$match">
            <xsl:copy-of select="$match"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy-of select="."/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" omit-xml-declaration="yes"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  <!-- For all taskItem in file1.xml -->
  <xsl:template match="taskItem">
    <!-- Get all taskItems from file2.xml -->
    <xsl:variable name="tiother" select="document('file2.xml')/Schedule/taskItem" />
    <!-- Get measurement text from current and other taskItems (from file1.xml and file2.xml) -->
    <xsl:variable name="namethis" select="./measurements/measurement/text()" />
    <xsl:variable name="nameother" select="$tiother/measurements/measurement/text()" />
    <xsl:choose>
      <!-- if the measurement texts are the same -->
      <xsl:when test="$namethis = $nameother">
        <!-- Yes ? create a new taskItem updated -->
        <xsl:element name="taskItem">
          <!-- Get taskId from the current task item (the one in file1.xml) -->
          <xsl:attribute name="taskId"><xsl:value-of select="./@taskId"/></xsl:attribute>
          <!-- Get startDate from the current task item (the one in file1.xml) -->
          <xsl:attribute name="startDate"><xsl:value-of select="./@startDate"/></xsl:attribute>
          <!-- Get stopDate from the other task item (the one in file2.xml) -->
          <xsl:attribute name="stopDate"><xsl:value-of select="$tiother/@stopDate"/></xsl:attribute>
          <!-- Get the measurements from the current task item (the one in file1.xml) -->
          <xsl:copy-of select="./measurements"/>
          <!-- Get the timings from the other task item (the one in file2.xml) -->
          <xsl:copy-of select="$tiother/timings"/>
        </xsl:element>
      </xsl:when>
      <xsl:otherwise>
        <!-- No ? just copy the current taskItem -->
        <xsl:copy-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>