XSLT - 如何计算XML中的标记数

时间:2015-04-12 15:11:20

标签: xslt count token tokenize

我有一个标记化模板,将XML元素文本拆分为HTML点。我希望能够计算出&#39 ;;'的总次数。分隔符出现在特定节点上。我怎么能实现这个目标呢?

XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="MainNode/Publications/publication_book/text()[normalize-space()]" name="split">
     <xsl:param name="pText" select="."/>
     <xsl:if test="normalize-space($pText)">
       <li>
         <xsl:call-template name="telephone">
           <xsl:with-param name="pText" select="substring-before(concat($pText, ';'), ';')"/>
         </xsl:call-template>
       </li>
       <xsl:call-template name="split">
         <xsl:with-param name="pText" select="substring-after($pText, ';')"/>
       </xsl:call-template>
     </xsl:if> 
 </xsl:template>


 <xsl:template match="MainNode/Publications/specific_node_that_has_no_li/text()[normalize-space()]" name="telephone">
     <xsl:param name="pText" select="."/>
     <xsl:if test="normalize-space($pText)">
         <xsl:call-template name="replace">
           <xsl:with-param name="pText" select="substring-before(concat($pText, ';'), ';')"/>
         </xsl:call-template>
       <xsl:call-template name="telephone">
         <xsl:with-param name="pText" select="substring-after($pText, ';')"/>
       </xsl:call-template>
     </xsl:if> 
 </xsl:template>

  <xsl:template name="replace">
   <xsl:param name="pText"/>
   <xsl:if test="normalize-space($pText)">
        <xsl:call-template name="italic">
        <xsl:with-param name="pText" select="substring-before(concat($pText, '*'),'*')"/>
        </xsl:call-template>
       <xsl:if test="contains($pText, '*')">
           <br/>           
         <xsl:call-template name="replace">
           <xsl:with-param name="pText" select="substring-after($pText, '*')"/>
         </xsl:call-template>
       </xsl:if>
    </xsl:if>
</xsl:template> 

<xsl:template name="italic">
    <xsl:param name="pText"/>
    <xsl:param name="delimiter" select="'^'"/>
    <xsl:choose>
        <xsl:when test="contains($pText, $delimiter) and contains(substring-after($pText, $delimiter), $delimiter)">        
                <xsl:call-template name="bold">
                <xsl:with-param name="pText" select="substring-before($pText, $delimiter)"/>
                </xsl:call-template>
            <i>
                <xsl:call-template name="bold">
                <xsl:with-param name="pText" select="substring-before(substring-after($pText, $delimiter), $delimiter)"/>
                </xsl:call-template>
            </i>
            <!-- recursive call -->
            <xsl:call-template name="italic">
                <xsl:with-param name="pText" select="substring-after(substring-after($pText, $delimiter), $delimiter)"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
        <xsl:call-template name="bold">
        <xsl:with-param name="pText" select="$pText"/>
        </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>


<xsl:template name="bold">
    <xsl:param name="pText"/>
    <xsl:param name="delimiter" select="'?'"/>
    <xsl:choose>
        <xsl:when test="contains($pText, $delimiter) and contains(substring-after($pText, $delimiter), $delimiter)">
            <xsl:value-of select="substring-before($pText, $delimiter)"/>
            <b>
                <xsl:value-of select="substring-before(substring-after($pText, $delimiter), $delimiter)"/>
            </b>
            <!-- recursive call -->
            <xsl:call-template name="bold">
                <xsl:with-param name="pText" select="substring-after(substring-after($pText, $delimiter), $delimiter)"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$pText"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="/">
 <html>
<head>
</head>
 <body>
<xsl:for-each select="MainNode/Publications">

  <!-- The count for number of publication_book which in the example XML is 3 should be outputted here -->

</xsl:for-each>     
 </body>
 </html>
</xsl:template>
</xsl:stylesheet>

示例XML:

<MainNode>
<Publications>
        <publication_book>
            ?test?,test., (2012), A new latex price forecasting model to reduce the risk of rubber test in Thailand. ^Handbook on test^*
            ^making:^ Vol 2:^Risk management in test making,^ 33(10), 191-203, New York.;

            test., ?test J.?, Clayden, J., (2010), test Production using Intelligent Time Series Analysis to Support ^Decision^* 
            ^Makers. test Support Systems, Advances In^, 43 ? 56, Croatia.;

            test., Lam, P., ?test.?, Li, H., (2010), test to the Temporal Data-Context of an Alarm of Interest. ^Dynamic and Advanced Data^* 

            ^Mining for test Technological Development: test and Systemic Approaches^, 18-39, USA, test. 
        </publication_book> 
</Publications>
</MainNode>

注意:我使用的是XSLT 1.0。

1 个答案:

答案 0 :(得分:2)

  

我希望能够算出&#39 ;;&#39;的总次数。   令牌发生在特定节点上。

我认为你的意思是&#39 ;;&#39; 分隔符,而不是令牌。你没有说出你需要的方式或地点,但你可以很容易地使用这个号码来获得这个号码:

translate($text, translate($text, ';', ''), '')

令牌的数量当然要高1,所以你想要使用类似的东西:

<xsl:template match="current | background | etc.">
    <xsl:variable name="number-of-tokens" select="string-length(translate(., translate(., ';', ''), '')) + 1" />
    <!-- the rest of the template -->
</xsl:template>

请注意,这发生在匹配元素列表的模板中 - 因此每个匹配的元素都会执行自己的计数。