如何使用 XSLT 合并两个相似的 XML 文件?

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

我有两个结构相似的 XML 文件。需要使用 XSLT 将这些 xml 文件合并为一个。

01.xml(有两个引用 REF01 和 REF10)

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<common-indicators>
    <common-indicator>
        <reference>REF01</reference>
        <name>name1</name>
        <reports>
            <report>
                <id>15</id>
                <name>name15</name>
            </report>
            <report>
                <id>16</id>
                <name>name16</name>
            </report>
        </reports>
    </common-indicator>
    <common-indicator>
        <reference>REF10</reference>
        <name>name10</name>
        <reports>
            <report>
                <id>30</id>
                <name>name30</name>
            </report>
            <report>
                <id>32</id>
                <name>name32</name>
            </report>
            <report>
                <id>34</id>
                <name>name34</name>
            </report>
        </reports>
    </common-indicator>
</common-indicators>

XSLT 转换(包括 xml 文件作为 param1 与两个引用 REF02 和 REF10 合并):

 <xsl:param name="param1">
    <common-indicators>
        <common-indicator>
            <reference>REF02</reference>
            <name>name2</name>
            <reports>
                <report>
                    <id>17</id>
                    <name>name17</name>
                </report>
                <report>
                    <id>18</id>
                    <name>name18</name>
                </report>
            </reports>
        </common-indicator>
        <common-indicator>
            <reference>REF10</reference>
            <name>name10</name>
            <reports>
                <report>
                    <id>36</id>
                    <name>name36</name>
                </report>
                <report>
                    <id>38</id>
                    <name>name38</name>
                </report>
                <report>
                    <id>40</id>
                    <name>name40</name>
                </report>
            </reports>
        </common-indicator>
    </common-indicators>
 </xsl:param>

<xsl:variable name="updateItems" select="$param1/common-indicators/common-indicator" /> 

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


<xsl:template match="common-indicators">
     <xsl:copy>
        <xsl:apply-templates select="common-indicator" />
        <xsl:apply-templates select="$updateItems" />
    </xsl:copy>
  </xsl:template>

xml xslt
1个回答
1
投票

XSLT 3.0 引入了合并功能。

这是一个为您提供的概念示例。

List1.xml

<?xml version="1.0"?>
<list>
   <item id="1">
      <descr ref="a"/>
      <descr ref="b"/>
   </item>
   <item id="2">
      <descr ref="c"/>
      <descr ref="d"/>
   </item>
   <item id="3">
      <descr ref="e">one</descr>
      <descr ref="f">one</descr>
   </item>
</list>

List2.xml

<?xml version="1.0"?>
<list>
   <item id="4">
      <descr ref="z"/>
      <descr ref="y"/>
   </item>
</list>

XSLT 3.0

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
    <xsl:strip-space elements="*"/>
    
    <!--fully qualified path's spaces shall be encoded via encode-for-uri()-->
    <!--directory and file names are case sensitive-->
    <xsl:param name="directory" select="'c:/XSLT30/Merging two XML files_XSLT30'"/>
    <xsl:param name="wildcard" select="'List*.xml'"/>
    
    <!--<xsl:mode streamable="yes"/>-->
    <xsl:mode on-no-match="shallow-copy"/>
    
    <xsl:template match="/">
        <list>
            <xsl:merge>
                <xsl:merge-source for-each-item="collection('file:///' || encode-for-uri($directory) || '?strip-space=yes;select=' || $wildcard)"
                    select="list/item">
                    <xsl:merge-key select="@id"
                        order="ascending"/>
                </xsl:merge-source>
                <xsl:merge-action>
                    <xsl:sequence select="current-merge-group()"/>
                </xsl:merge-action>
            </xsl:merge>
        </list>
    </xsl:template>
</xsl:stylesheet>

输出

<?xml version="1.0" encoding="UTF-8"?>
<list>
   <item id="1">
      <descr ref="a"/>
      <descr ref="b"/>
   </item>
   <item id="2">
      <descr ref="c"/>
      <descr ref="d"/>
   </item>
   <item id="3">
      <descr ref="e">one</descr>
      <descr ref="f">one</descr>
   </item>
   <item id="4">
      <descr ref="z"/>
      <descr ref="y"/>
   </item>
</list>
© www.soinside.com 2019 - 2024. All rights reserved.