2011-10-14 65 views
0

我有一個帶有文本節點的XML,我需要使用XSLT 2.0將此字符串拆分爲多個塊。例如:使用XSLT的塊字符串

<tag> 
    <text>This is a long string 1This is a long string 2This is a long string 3This is a long string 4</text> 
</tag> 

輸出應該是:

<tag> 
    <text>This is a long string 1</text> 
    <text>This is a long string 2</text> 
    <text>This is a long string 3</text> 
    <text>This is a long string 4</text> 
</tag> 

注意,我故意設置的塊大小每個語句的長度,這樣的例子更容易閱讀和寫字,但轉型應該接受任何值(這個值可以硬編碼)。

+0

有一噸的在SO約XSLT串分割的問題。關鍵字:「XSLT split」 –

回答

1

這XSLT 1.0轉化

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:param name="pChunkSize" select="23"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="text/text()" name="chunk"> 
    <xsl:param name="pText" select="."/> 

    <xsl:if test="string-length($pText) >0"> 
    <text><xsl:value-of select= 
    "substring($pText, 1, $pChunkSize)"/> 
    </text> 
    <xsl:call-template name="chunk"> 
    <xsl:with-param name="pText" 
    select="substring($pText, $pChunkSize+1)"/> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔施加:

<tag> 
    <text>This is a long string 1This is a long string 2This is a long string 3This is a long string 4</text> 
</tag> 

產生想要的,正確的結果

<tag> 
    <text> 
     <text>This is a long string 1</text> 
     <text>This is a long string 2</text> 
     <text>This is a long string 3</text> 
     <text>This is a long string 4</text> 
     <text/> 
    </text> 
</tag> 

二, XSLT 2.0溶液(非遞歸):

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:param name="pChunkSize" select="23"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="text/text()"> 
    <xsl:variable name="vtheText" select="."/> 
    <xsl:for-each select= 
     "0 to string-length() idiv $pChunkSize"> 
    <text> 
    <xsl:sequence select= 
    "substring($vtheText, . *$pChunkSize +1, $pChunkSize) "/> 
    </text> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
+0

出色的工作!但是你認爲這可以在不使用遞歸的情況下完成嗎?謝謝。 – Paul

+0

@Paul:不在XSLT 1.0中 - 至少對於無限數量的塊。如果知道塊的數量不超過某個合理的小限制,那麼這可以在不遞歸的情況下完成。在XSLT 2.0中,無需遞歸即可輕鬆完成。我很想知道你用遞歸找到了什麼問題? –

+0

完全沒問題。我只是想知道我是否可以避免遞歸。順便說一下,我*使用XSLT 2.0。 – Paul