在Regex中调用另一个模板

时间:2013-11-20 09:12:41

标签: regex xslt-2.0

我有下面的XML

<title>Conduct of external affairs <content-style font-style="italic">via</content-style> NGOs</title>

这里当我试图与REGEX匹配时,它给我一个错误

我正在使用的模板是

 <?xml version='1.0'?>
<xslt:stylesheet version="2.0" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:param name="Conjunction">(of)|(to)|(and)|(the)</xsl:param>

  <xsl:template match="title">
    <xsl:call-template name="changeUpperCase">
      <xsl:with-param name="Text" select="text()"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="changeUpperCase">
    <xsl:param name="Text"/>
    <xsl:value-of select="for $EachToken in tokenize(lower-case($Text), ' ')
                          return
                          if(matches($EachToken, $Conjunction))
                           then
                             $EachToken
                           else
                           concat(upper-case(substring($EachToken, 1, 1)), substring($EachToken, 2))"/>

  </xsl:template>

</xslt:stylesheet>

我得到的错误是

 XSLT 2.0 Debugging Error: Error: file:///C:/Users/u0138039/Desktop/Proview/HK/The%20Law%20of%20the%20Hong%20Kong%20Constitution/The%20Law%20of%20the%20Hong%20Kong%20Constitution/XSLT/Chapters.xsl:39: Wrong occurrence to match required sequence type -   Details: -     XPTY0004: The supplied sequence ('2' item(s)) has the wrong occurrence to match the sequence type xs:string ('zero or one')

我还宣布了内容风格的模板,但我不知道如何链接它。

<xsl:template match="content-style">
<xsl:choose>
    <xsl:when test="./@format">
        <span class="{concat('format-',@format)}">
              <xsl:apply-templates/>
        </span>
    </xsl:when>
    <xsl:otherwise>
     <xsl:variable name="fontStyle">
            <xsl:value-of select="concat('font-style-',@font-style)"/>
        </xsl:variable>
        <span class="{$fontStyle}">
            <xsl:value-of select="."/>
            <xsl:apply-templates select="para"/>
        </span>
    </xsl:otherwise>
</xsl:choose>    
    </xsl:template>

但如果我使用下面的XML代码

,则上述模板正常工作
<title>IS HONG KONG AN INTERNATIONAL PERSON?</title>

案例2:

 <title>PREPARATION FOR TRANSFER OF SOVEREIGNTY</title>

这应该转换为

Preperation for Transfer of Sovereignty

请让我知道如何解决这个问题。

由于

1 个答案:

答案 0 :(得分:1)

我建议使用匹配模板的一致代码样式而不是调用模板:

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

  <xsl:param name="Conjunction">(of)|(to)|(and)|(the)|(for)</xsl:param>

  <xsl:template match="title">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="title/text()">
    <xsl:value-of select="for $EachToken in tokenize(lower-case(.), ' ')
                          return
                          if(matches($EachToken, $Conjunction))
                           then
                             $EachToken
                           else
                           concat(upper-case(substring($EachToken, 1, 1)), substring($EachToken, 2))"/>

  </xsl:template>

  <xsl:template match="content-style">
     <xsl:variable name="fontStyle" select="concat('font-style-',@font-style)"/>
        <span class="{$fontStyle}">
            <xsl:value-of select="."/>
            <xsl:apply-templates select="para"/>
        </span>
  </xsl:template>

  <xsl:template match="content-style[@format]">
        <span class="{concat('format-',@format)}">
              <xsl:apply-templates/>
        </span>
  </xsl:template>

</xsl:stylesheet>

这样,错误就会消失,因为text处理的title元素的apply-templates子节点有一个模板。

在当前代码with-param name="Text" select="text()"中,如果元素具有混合内容,那么text子节点序列将传递给模板,lower-case调用具有错误类型的参数。

现在应该应用content-style元素的模板,但我不确定它们是否会完全按照您的要求进行操作,因为您没有详细说明。如果您的问题的第二部分仍然存在问题,请发布一个新问题。

根据您的评论,我修改了样式表以使用analyze-string

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

  <xsl:param name="Conjunction">^(of|to|and|the|for)$</xsl:param>

  <xsl:template match="title">
    <xsl:copy>
       <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="title/text()">
    <xsl:analyze-string select="." regex="(\w)(\w*)">
      <xsl:matching-substring>
        <xsl:value-of
          select="if (matches(., $Conjunction, 'i'))
                  then lower-case(.)
                  else concat(upper-case(regex-group(1)), lower-case(regex-group(2)))"/>
      </xsl:matching-substring>
      <xsl:non-matching-substring>
        <xsl:value-of select="."/>
      </xsl:non-matching-substring>
    </xsl:analyze-string>
  </xsl:template>

  <xsl:template match="content-style">
     <xsl:variable name="fontStyle" select="concat('font-style-',@font-style)"/>
        <span class="{$fontStyle}">
            <xsl:apply-templates/>
        </span>
  </xsl:template>

  <xsl:template match="content-style[@format]">
        <span class="{concat('format-',@format)}">
              <xsl:apply-templates/>
        </span>
  </xsl:template>

</xsl:stylesheet>

现在Saxon 9.5转换

<root>
  <title>HOW HIGH IS THE &#x201C;HIGH DEGREE OF AUTONOMY&#x2019; OF HONG KONG?</title>
  <title>PREPARATION FOR TRANSFER OF SOVEREIGNTY</title>
  <title>Conduct of external affairs <content-style font-style="italic">via</content-style> NGOs</title>
</root>

  <title>How High Is the “High Degree of Autonomy’ of Hong Kong?</title>
  <title>Preparation for Transfer of Sovereignty</title>
  <title>Conduct of External Affairs <span class="font-style-italic">via</span> Ngos</title>