如何使用XSLT连接多个XML文件?
我有几个结构类似的XML文件。需要使用XSLT将这些文件合并为一个文件,并按如下所示分组 01.xml(报告编号1,两组-“本地”和“网络”)如何使用XSLT连接多个XML文件?,xml,xslt,Xml,Xslt,我有几个结构类似的XML文件。需要使用XSLT将这些文件合并为一个文件,并按如下所示分组 01.xml(报告编号1,两组-“本地”和“网络”) 22 33 44 55 66 77 02.xml(报告编号2,两组-“本地”和“网络”)) 33 44 55 66 77 88 03.xml(报告编号3,两组-“本地”和“网络”) 44 55 66 77 88 99 分组的预期结果: <Reports> <Year Year="2019"> <
22
33
44
55
66
77
02.xml(报告编号2,两组-“本地”和“网络”))
33
44
55
66
77
88
03.xml(报告编号3,两组-“本地”和“网络”)
44
55
66
77
88
99
分组的预期结果:
<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>
22
33
44
33
44
55
44
55
66
55
66
77
66
77
88
77
88
99
也许您可以指定确切的问题是什么?是关于阅读文件吗?用于此
我想:
-将元素的所有子体存储在$group{name}
-将变量中的项目分组
-为新文档创建一个结构
-使用
或
输出变量所属的值
比如说,
将元素ReportN1存储在变量中:
<xsl:variable name="xml_01_local-r1" select="document('01.xml')//group[@name='local']/ReportN1"/>
以后像这样输出它
<Group name="Local">
<xsl:copy-of select="$xml_01_local-r1"/>
</Group>
当然,应该有更有效的方法来实现这一点,但这一种会起作用。如果您知道您正好有三个文档,您可以使用
doc
函数(例如
)将它们作为三个单独的参数加载,然后这只是一个嵌套分组的问题,下面是一个XSLT 3(由Saxon 9.8和更高版本支持)我所做的示例用于组合分组键的一个分组:
<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>
在这里,我内联了示例XML数据,但您当然也可以使用doc
函数加载它们,或者通常使用Saxon 9的collection
函数加载多个文档。然后将
替换为
对于XSLT 2,您将在第二个分组上使用nocomposite
属性,然后使用groupby=“concat(@mon1,|,@mon2)”
和代码>也不可用,因此如果订单重要,则使用select=“for$doc in$docs return$doc/*/Year”
而不是select=“$docs!*!Year”
我假设样式表与虚拟输入文档一起使用,或者与-it
一起用作Saxon 9.8及更高版本的命令行选项,如果使用较旧版本,这将是您需要的另一个更改,我认为XSLT2不允许
,因此您需要使用不同的名称,如
,并使用-it:main
启动Saxon,您使用哪个XSLT版本,哪个XSLT处理器?这似乎只是一个分组问题,或者,如果您使用XSLT 3,可能是xsl:merge
的一个用例。可能是Martin的重复,我使用Saxon XSLT处理器,XSLT版本2.0OS-50101,我在xsl转换方面没有太大的过期性,您能给我一些示例吗?谢谢您的详细回答,Martin。这很有效!
<xsl:variable name="xml_01_local-r1" select="document('01.xml')//group[@name='local']/ReportN1"/>
<Group name="Local">
<xsl:copy-of select="$xml_01_local-r1"/>
</Group>
<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>