考慮下面的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