2010-09-12 96 views
2

考慮下面的XML文檔:使用XSL單個XML文檔轉換成多個文檔

<XML> 
<doc1> 
</doc1> 
<doc2> 
</doc2> 
<XML> 

我希望能使用XSL轉換生成2個XML文檔:

<XML> 
<doc1> 
</doc1> 
<XML> 

而且

<XML> 
</doc2> 
<doc2> 
<XML> 

這可能嗎?

+0

嘿Oded,你打我吧 - 在iPhone上編輯xml不是那麼容易! – 78lro 2010-09-12 18:51:14

+0

iPhone,呃? Showoff;) – Oded 2010-09-12 18:51:45

+0

好問題(+1)。查看我對XSLT 1.0和XSLT 2.0解決方案的回答。 – 2010-09-12 21:06:53

回答

3

在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 
+0

+1優秀的答案,包括沒有擴展解決方案的XSLT 1.0! – 2010-09-13 13:39:33

0

我們有這個問題曾經並通過輕微作弊解決它:

第1步:創建一個包含由程序指令或意見不同的分離XML腳本一個大文件。 第2步:使用程序將文件剪切成單獨的文件。

請注意,您的中間結果是無效的xml,但最終結果是有效的。

<doc1>..<doc1> 
<!-- SEP --> 
<doc2>..<doc2> 
<!-- SEP --> 
<doc3>..<doc3>