首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用XSLT连接多个XML文件?

如何使用XSLT连接多个XML文件?
EN

Stack Overflow用户
提问于 2019-09-11 21:20:20
回答 2查看 76关注 0票数 0

我有几个结构类似的XML文件。需要使用XSLT将这些文件合并为一个文件,如下所示。

01.xml (报告编号1,两组-“本地”和"Web")

代码语言:javascript
复制
<Reports>
   <Year Year="2019">
      <Month mon1="1" mon2="12">
         <Group name="Local">
            <ReportN1>
              <Data Kods="10011">
                 <A-1>22</A-1>
                 <A-2>33</A-2>
                 <A-3>44</A-3>
              </Data>
            </ReportN1>
         </Group>
         <Group name="Web">
            <ReportN1>
              <Data Kods="10011">
                 <A-1>55</A-1>
                 <A-2>66</A-2>
                 <A-3>77</A-3>
              </Data>
            </ReportN1>
         </Group>
      </Month>
   </Year>
</Reports>

02.xml (报告第2号,两组-“本地”和“Web”)

代码语言:javascript
复制
<Reports>
   <Year Year="2019">
      <Month mon1="1" mon2="12">
         <Group name="Local">
            <ReportN2>
              <Data Kods="10022">
                 <B-1>33</B-1>
                 <B-2>44</B-2>
                 <B-3>55</B-3>
              </Data>
            </ReportN2>
         </Group>
         <Group name="Web">
            <ReportN2>
              <Data Kods="10022">
                 <B-1>66</B-1>
                 <B-2>77</B-2>
                 <B-3>88</B-3>
              </Data>
            </ReportN2>
         </Group>
      </Month>
   </Year>
</Reports>

03.xml (报告第3号,两组-“本地”和"Web")

代码语言:javascript
复制
<Reports>
   <Year Year="2019">
      <Month mon1="1" mon2="12">
         <Group name="Local">
            <ReportN3>
              <Data Kods="10033">
                 <C-1>44</C-1>
                 <C-2>55</C-2>
                 <C-3>66</C-3>
              </Data>
            </ReportN3>
         </Group>
         <Group name="Web">
            <ReportN3>
              <Data Kods="10033">
                 <C-1>77</C-1>
                 <C-2>88</C-2>
                 <C-3>99</C-3>
              </Data>
            </ReportN3>
         </Group>
      </Month>
   </Year>
</Reports>

分组的预期结果:

代码语言:javascript
复制
<Reports>
   <Year Year="2019">
      <Month mon1="1" mon2="12">
         <Group name="Local">
            <ReportN1>
              <Data Kods="10011">
                 <A-1>22</A-1>
                 <A-2>33</A-2>
                 <A-3>44</A-3>
              </Data>
            </ReportN1>
            <ReportN2>
              <Data Kods="10022">
                 <B-1>33</B-1>
                 <B-2>44</B-2>
                 <B-3>55</B-3>
              </Data>
            </ReportN2>
            <ReportN3>
              <Data Kods="10033">
                 <C-1>44</C-1>
                 <C-2>55</C-2>
                 <C-3>66</C-3>
              </Data>
            </ReportN3>
         </Group>
         <Group name="Web">
            <ReportN1>
              <Data Kods="10011">
                 <A-1>55</A-1>
                 <A-2>66</A-2>
                 <A-3>77</A-3>
              </Data>
            </ReportN1>
            <ReportN2>
              <Data Kods="10022">
                 <B-1>66</B-1>
                 <B-2>77</B-2>
                 <B-3>88</B-3>
              </Data>
            </ReportN2>
            <ReportN3>
              <Data Kods="10033">
                 <C-1>77</C-1>
                 <C-2>88</C-2>
                 <C-3>99</C-3>
              </Data>
            </ReportN3>
         </Group>
      </Month>
   </Year>
</Reports>
EN

回答 2

Stack Overflow用户

发布于 2019-09-11 22:04:25

也许你可以详细说明问题的确切原因是什么?是关于阅读文档的吗?为此,请使用document()

我将:-将元素的所有后代存储在$group_{name}中-对变量中的项进行分组-为新文档创建一个结构-使用<xsl:copy-of><xsl:sequence>输出变量所属的值

例如,

将元素ReportN1存储在变量中:

代码语言:javascript
复制
<xsl:variable name="xml_01_local-r1" select="document('01.xml')//group[@name='local']/ReportN1"/>

稍后输出如下所示

代码语言:javascript
复制
<Group name="Local">
    <xsl:copy-of select="$xml_01_local-r1"/>
</Group>

当然,应该有更有效的方法来做到这一点,但这一种方法将会奏效。

票数 0
EN

Stack Overflow用户

发布于 2019-09-11 23:13:43

如果您知道您正好有三个文档,您可以使用doc函数(例如<xsl:param name="doc1" select="doc('01.xml')"/>)将它们作为三个单独的参数加载,然后这就是一个嵌套分组的问题,下面是一个XSLT3(受Saxon9.8和更高版本支持)示例,正如我已经用于组合分组键的一个分组:

代码语言:javascript
复制
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:param name="doc1"><Reports>
   <Year Year="2019">
      <Month mon1="1" mon2="12">
         <Group name="Local">
            <ReportN1>
              <Data Kods="10011">
                 <A-1>22</A-1>
                 <A-2>33</A-2>
                 <A-3>44</A-3>
              </Data>
            </ReportN1>
         </Group>
         <Group name="Web">
            <ReportN1>
              <Data Kods="10011">
                 <A-1>55</A-1>
                 <A-2>66</A-2>
                 <A-3>77</A-3>
              </Data>
            </ReportN1>
         </Group>
      </Month>
   </Year>
</Reports>
</xsl:param>

  <xsl:param name="doc2"><Reports>
   <Year Year="2019">
      <Month mon1="1" mon2="12">
         <Group name="Local">
            <ReportN2>
              <Data Kods="10022">
                 <B-1>33</B-1>
                 <B-2>44</B-2>
                 <B-3>55</B-3>
              </Data>
            </ReportN2>
         </Group>
         <Group name="Web">
            <ReportN2>
              <Data Kods="10022">
                 <B-1>66</B-1>
                 <B-2>77</B-2>
                 <B-3>88</B-3>
              </Data>
            </ReportN2>
         </Group>
      </Month>
   </Year>
</Reports></xsl:param>

  <xsl:param name="doc3">
<Reports>
   <Year Year="2019">
      <Month mon1="1" mon2="12">
         <Group name="Local">
            <ReportN3>
              <Data Kods="10033">
                 <C-1>44</C-1>
                 <C-2>55</C-2>
                 <C-3>66</C-3>
              </Data>
            </ReportN3>
         </Group>
         <Group name="Web">
            <ReportN3>
              <Data Kods="10033">
                 <C-1>77</C-1>
                 <C-2>88</C-2>
                 <C-3>99</C-3>
              </Data>
            </ReportN3>
         </Group>
      </Month>
   </Year>
</Reports>      
  </xsl:param>


  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/" name="xsl:initial-template">
    <Report>
        <xsl:for-each-group select="$doc1/*/Year, $doc2/*/Year, $doc3/*/Year" group-by="@Year">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:for-each-group select="current-group()/Month" composite="yes" group-by="@mon1, @mon2">
                    <xsl:copy>
                        <xsl:copy-of select="@*"/>
                        <xsl:for-each-group select="current-group()/Group" group-by="@name">
                            <xsl:copy>
                                <xsl:copy-of select="@*, current-group()!*"/>
                            </xsl:copy>
                        </xsl:for-each-group>
                    </xsl:copy>
                </xsl:for-each-group>
            </xsl:copy>
        </xsl:for-each-group>
    </Report>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/pPJ8LUU

在这里,我已经内联了示例XML数据,当然,您也可以使用doc函数加载它们,或者通常在Saxon9中使用collection函数,例如<xsl:param name="docs" select="collection('?select=*.xml')"/>来加载几个文档。然后将<xsl:for-each-group select="$doc1/*/Year, $doc2/*/Year, $doc3/*/Year" group-by="@Year">替换为<xsl:for-each-group select="$docs!*!Year" group-by="@Year">

对于XSLT2,您可以在第二个分组上不使用composite属性,但是group-by="concat(@mon1, '|', @mon2)"!也不可用,所以如果顺序很重要,那么使用select="for $doc in $docs return $doc/*/Year"而不是select="$docs!*!Year"

我假设样式表与虚拟输入文档一起使用,或者使用-it作为Saxon9.8和更高版本的命令行选项,如果使用旧版本,这将是另一个需要更改的地方,我认为XSLT2不允许使用<xsl:template match="/" name="xsl:initial-template">,因此您需要使用一个不同的名称,如<xsl:template match="/" name="main">,并使用-it:main启动Saxon。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57890184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档