考虑下面的XML文档:使用XSL单个XML文档转换成多个文档
<XML>
<doc1>
</doc1>
<doc2>
</doc2>
<XML>
我希望能使用XSL转换生成2个XML文档:
<XML>
<doc1>
</doc1>
<XML>
而且
<XML>
</doc2>
<doc2>
<XML>
这可能吗?
考虑下面的XML文档:使用XSL单个XML文档转换成多个文档
<XML>
<doc1>
</doc1>
<doc2>
</doc2>
<XML>
我希望能使用XSL转换生成2个XML文档:
<XML>
<doc1>
</doc1>
<XML>
而且
<XML>
</doc2>
<doc2>
<XML>
这可能吗?
在XSLT 1.0,不可能创建多于一个的树作为任何改造的输出,但在XSLT 2.0这是可以做到很容易。
在XSLT 1.0中,可以使用EXSLT的扩展元素<exsl:document>
。施加时
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pDocElement" select="'doc1'"/>
<xsl:template match="/*/*">
<xsl:if test="name()=$pDocElement">
<xsl:apply-templates select="." mode="copy"/>
</xsl:if>
</xsl:template>
<xsl:template match="node()" mode="copy">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
:
或者,一个可具有一个转换,即提供了一种全局(和外部指定的)参数,包含必须被提取到单个文档中的元素的元素名称在这个XML文档(基于所提供的一个):
<t>
<doc1>
Doc 1 Content
</doc1>
<doc2>
Doc 2 Content
</doc2>
<doc3>
Doc 3 Content
</doc3>
</t>
有用结果产生:
<doc1>
Doc 1 Content
</doc1>
而且您将为每个元素运行此转换一次,其子树应该被提取到单独的文档中。
这是一个XSLT 2。0溶液:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*" mode="copy">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/*[starts-with(name(),'doc')]">
<xsl:result-document href="{name()}.xml">
<xsl:apply-templates select="." mode="copy"/>
</xsl:result-document>
</xsl:template>
<xsl:template match="/*">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
当在下面的XML文档被应用该转化(基于所提供的一个):
<t>
<doc1>
Doc 1 Content
</doc1>
<doc2>
Doc 2 Content
</doc2>
<doc3>
Doc 3 Content
</doc3>
</t>
结果是正确地输出到三个文件:
Saxon 9.1.0.5J from Saxonica
Java version 1.6.0_21
Stylesheet compilation time: 868 milliseconds
Loading net.sf.saxon.event.MessageEmitter
Writing to file:/C:/Program%20Files/Java/jre6/bin/doc1.xml
Writing to file:/C:/Program%20Files/Java/jre6/bin/doc2.xml
Writing to file:/C:/Program%20Files/Java/jre6/bin/doc3.xml
Execution time: 151 milliseconds
Memory used: 11467936
NamePool contents: 18 entries in 18 chains. 6 prefixes, 6 URIs
+1优秀的答案,包括没有扩展解决方案的XSLT 1.0! – 2010-09-13 13:39:33
我们有这个问题曾经并通过轻微作弊解决它:
第1步:创建一个包含由程序指令或意见不同的分离XML脚本一个大文件。 第2步:使用程序将文件剪切成单独的文件。
请注意,您的中间结果是无效的xml,但最终结果是有效的。
例
<doc1>..<doc1>
<!-- SEP -->
<doc2>..<doc2>
<!-- SEP -->
<doc3>..<doc3>
嘿Oded,你打我吧 - 在iPhone上编辑xml不是那么容易! – 78lro 2010-09-12 18:51:14
iPhone,呃? Showoff;) – Oded 2010-09-12 18:51:45
好问题(+1)。查看我对XSLT 1.0和XSLT 2.0解决方案的回答。 – 2010-09-12 21:06:53