XSLT从文档开头的字符串长度

时间:2013-12-02 16:30:25

标签: xhtml xslt-2.0

我有这个XSLT来拆分一个25 MB的XHTML文件。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <xsl:apply-templates select="html/body"/>
</xsl:template>

<xsl:template match="body">
    <xsl:for-each-group select="node()" 
        group-starting-with="*[position()=1 or @class='toc']">            
        <xsl:if test="count(current-group()[self::*]) &gt; 0 ">
          <xsl:variable name="filename" select="concat('/home/t',position(),'.xml' )"/>
            <xsl:apply-templates/>
            <xsl:result-document 
                 indent="yes" method="xml" href="$filename}">                    
                <html>
                    <xsl:copy-of select="/html/@*"/>
                    <xsl:for-each select="/html/node()">
                        <xsl:choose>
                            <xsl:when test="not(self::body)">
                                <xsl:copy-of select="."/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:copy>
                                    <xsl:copy-of select="@*"/>
                                    <xsl:copy-of select="current-group()"/>
                                </xsl:copy>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:for-each>
                </html>
            </xsl:result-document>
        </xsl:if>
    </xsl:for-each-group>
</xsl:template>

<xsl:template match="text()"/>

</xsl:stylesheet>

它目前可以在找到@toc时拆分文件。我需要将其更改为对输出文件的 size 敏感,而不是在@toc处断开。

所需的最终状态:我希望结果文档大约为500KB。我认为position()可能是调节分裂点的最佳方法?我尝试了各种string-length()方法 - 我无法让它工作。此外,我认为空白可能是一个问题。

根据我对这些文档的计算,将文件拆分为<p class="i0">找到的150th position个增量,应该可靠地给我我需要的文件大小。

我想到达目的地的最佳方法是改变这一点:

group-starting-with="*[position()=1 or @class='toc']"

到目前为止,我还没有成功改变它。想法?

更新:我还没准备好说这个问题得到了解答,因为有人可能会有更好的主意。但是现在我正在使用group-starting-with="body/*[position()=1 or position() mod 350 = 0]"取得一些成功。它测试得很好。 更新2: group-starting-with="body/*[position()=1 or position() mod 350 = 0]"效果不佳。问题是它是for-each-loops中的位置,而不是整个文件。

1 个答案:

答案 0 :(得分:1)

  

成功的解决方案最终成为xslt 3.0累加器。

作为替代方案:

  

Dmitiri Novatchev XSLT 1.0解决方案:

     

这种转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output omit-xml-declaration="yes"/>

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

 <xsl:template match="/">
   <xsl:variable name="vResult">
 <xsl:apply-templates/>
   </xsl:variable>

   Length of output is: <xsl:text/>
   <xsl:value-of select="concat(string-length($vResult), '&#xA;')"/>

   <xsl:if test="string-length($vResult) &lt;= 1800">
 <xsl:copy-of select="$vResult"/>
   </xsl:if>
 </xsl:template>

</xsl:stylesheet>
  

应用于此source.xml时:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>
  

产生想要的结果:

     

输出长度为:51                01         02         03         04         05         06         07         08         09         10       

<强>参考