2010-10-27 74 views
29

我很难将XSLT打包成XSLT,但我听说可以将XML文件拆分为多个文件。基本上我想复制所有的元素到第一个文件和最后一个文件之后,然后为每个输出文件添加单个文件内容。使用XSLT将XML拆分为多个文件

如果有可能的话,有人能给我一些指示吗?

感谢,

complete.xml

<rootelem> 
    <elem> 
    <file attr1='1'> 
     <content>content file 1</content> 
    </file> 
    <file attr2='2'> 
     <content>content file 2</content> 
    </file> 
    <file attr3='3'> 
     <content>content file 3</content> 
    </file> 
    </elem> 
</rootelem> 

OUTPUT:

complete_PART1.xml

<rootelem> 
    <elem> 
    <file attr1='1'> 
     <content>content file 1</content> 
    </file> 
    </elem> 
</rootelem> 

complete_PART2.xml

<rootelem> 
    <elem> 
    <file attr2='2'> 
     <content>content file 2</content> 
    </file> 
    </elem> 
</rootelem> 

complete_PART3.xml

<rootelem> 
    <elem> 
    <file attr3='3'> 
     <content>content file 3</content> 
    </file> 
    </elem> 
</rootelem> 
+0

好问题,+1。查看我的答案,了解有关XSLT(1.0和2.0)产生多重输出结果的标准支持方向。 – 2010-10-27 18:43:13

+0

我有一个要求将大的XML文件分割成更小的文件,但我要写一个程序来做(它需要轮询一个文件夹和处理大于x megs的文件)​​ - 有很多不同的文件类型 - 例如,我不知道前面的XML结构,所以我需要一个通用的分离器 - 可以用XSLT来完成,还是应该使用.NET XML阅读工具? – Rodney 2011-07-26 07:43:59

+0

@ Rodney--你应该看看VTD-XML,它非常适合处理/分割大型XML – 2016-05-03 20:39:53

回答

14

在回答关于@ Dimitre的回答您的评论...

你写,

<xsl:template match="/"> 
    <xsl:for-each select="elem/file"> 
    <xsl:result-document method="xml" href="file_{@id}-output.xml"> 
     <xsl:copy-of select="."/> 
    </xsl:result-document> 
    </xsl:for-each> 
</xsl:template> 

这不完全匹配你的XML,它具有rootelem作为最外层的元素,和您的评论说root作为最外面的元素。你可能想是这样的:

<xsl:template match="/root"> 
    <xsl:for-each select="elem/file"> 
    <xsl:result-document method="xml" href="file_{@id}-output.xml"> 
     <root> 
     <xsl:copy-of select="/root/@*" /> 
     <elem> 
      <xsl:copy-of select="../@* | ." /> 
     </elem> 
     </root> 
    </xsl:result-document> 
    </xsl:for-each> 
</xsl:template> 

你可以更大胆,尝试使用<xsl:copy>而不是根和元素文字结果元素,但它似乎不值得的,除非他们打算改变。

+0

你是对的拉尔斯,对不起草率复制的实际文件。我做了类似于你所拥有的东西,但问题是root和elem有我需要维护的各种属性。但也许我可以以某种方式使用父母仍然试图围绕xslt包裹我的头。 – 2010-10-27 21:54:25

+0

@Nisse,我编辑了答案以保留root和elem的属性。 xsl:copy-of的问题在于你不能修改被复制的部分......你只需复制你选择的节点下的整个树。你不能添加或省略任何东西。所以你不能xsl:copy-of/root或/ root/elem。但是,如果你xsl:复制所需的属性,你的状态良好。 – LarsH 2010-10-28 01:36:54

12

这是不可能在纯XSLT 1.0以产生多于一个输出文件。为此,人们可以使用扩展元素。

在XSLT 2.0中,使用<xsl:result-document>元素。

+0

嗨Dimitre,谢谢你的回复。我现在正在使用xsl:result-document,它将文件拆分,但将作为顶级元素。但是,我想在每个生成的文件中保留。对此有何建议? < xsl:copy-of select =“。”/> 2010-10-27 20:19:14

+0

我可以知道如何在VS2010专业版中配置 。 – 2012-06-12 11:00:15

+0

@Jeevan:实现这一目标的唯一途径就是安装EXSLT-MVP--请参阅Oleg Tkachenko的公告:http://www.tkachenko.com/blog/archives/000293.html – 2012-06-12 12:00:15

2

如果你想使用

<xsl:result-document method="xml" href="file_{@id}-output.xml"> 

从ANT XSLT通话时,您需要使用2.0,只需添加以下您的ANT电话:

<classpath location="/home/ap/saxon/saxon8.jar" /> 

而且specifiy版本=” 2.0“ 并享受文件分割。

+0

@millebbi:对不起,但也许这应该在另一个问题,实际上询问有关ant与Saxon XSLT处理器集成... – 2011-01-18 00:34:54

+0

那么它会在两个,因为我也想用:,但ANT默认使用1.0,添加此ANT语句可以使用 millebii 2011-01-18 11:28:51