2013-03-26 139 views
0

我有下面的xslt。XSLT錯誤原因

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"> 
    <xsl:output method="html"/> 
    <xsl:template match="/"> 
     <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text> 
     <html> 
      <head> 
       <title> 
        <xsl:value-of select="index/title"/> 
       </title> 
       <link rel="stylesheet" href="er:#css" type="text/css"/> 
      </head> 
      <body> 
       <xsl:apply-templates/> 
      </body> 
     </html> 
    </xsl:template> 
    <xsl:template match="index"> 
     <div class="index"> 
      <xsl:variable name="num"> 
       <xsl:number level="any" format="01"/> 
      </xsl:variable> 
      <a name="BVI_IDX_{$num}"/> 
      <div class="index-title"> 
       <xsl:apply-templates select="title"/> 
       <xsl:value-of select="index/title/@text()"/> 
      </div> 
      <xsl:apply-templates select="child::node()[not(self::title)]"/> 
      <!--<xsl:apply-templates/>--> 
     </div> 
    </xsl:template> 
    <!--<xsl:template match="index"> 
     <div class="index"> 
      <div class="index-title"> 
       <xsl:value-of select="index/title/@text()"/> 
      </div> 
      <xsl:apply-templates/> 
     </div> 
    </xsl:template>--> 
    <xsl:template match="indexdiv"> 
     <div class="indexdiv"> 
      <xsl:apply-templates/> 
     </div> 
    </xsl:template> 
    <xsl:template match="indexdiv/title"> 

    </xsl:template> 
    <xsl:template match="indexentry"> 
     <div class="indexentry"> 
      <xsl:apply-templates/> 
     </div> 
    </xsl:template> 
    <xsl:template match="primaryie"> 
     <div class="primaryie"> 
      <xsl:apply-templates select="content-style"/> 
      <xsl:if test="contains(current()/text(), '.')"> 
       <xsl:variable name="numberString" select="substring(current()/text(), string-length(substring-before(current()/text(),'.'))-1)"/> 
       <xsl:call-template name="numbersToLink"> 
        <xsl:with-param name="numbersString" select="$numberString"/> 
       </xsl:call-template> 
      </xsl:if> 
     </div> 
    </xsl:template> 
    <xsl:template match="secondaryie"> 
     <xsl:variable name="textAll"> 
      <xsl:value-of select="text()"/> 
     </xsl:variable> 
     <xsl:variable name="textOnly"> 
      <xsl:choose> 
       <xsl:when test="contains($textAll,'.')"> 
        <xsl:value-of select="substring($textAll,1,string-length(substring-before($textAll,'.'))-1)"/> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:value-of select="text()"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:variable> 
     <xsl:variable name="textAll1"> 
      <xsl:value-of select="text()"/> 
     </xsl:variable> 
     <xsl:variable name="numbersOnly"> 
      <xsl:choose> 
       <xsl:when test="contains($textAll1,'.')"> 
        <xsl:value-of select="substring($textAll1,string-length($textOnly))"/> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:variable> 
     <div class="secondaryie"> 
      <xsl:value-of select="$textOnly"/> 
      <xsl:call-template name="numbersToLink"> 
       <xsl:with-param name="numbersString" select="$numbersOnly"/> 
      </xsl:call-template> 
      <xsl:if test="current()/content-style/node()"> 
       <xsl:for-each select="current()/content-style"> 
        <xsl:call-template name="content-style"/> 
       </xsl:for-each> 
      </xsl:if> 
     </div> 
    </xsl:template> 
    <xsl:template match="tertiaryie"> 
     <xsl:variable name="tertClassType"> 
      <xsl:value-of select="@level"/> 
     </xsl:variable> 
     <xsl:variable name="tertClassTypName"> 
      <xsl:value-of select="concat('tertiaryie-', $tertClassType)"/> 
     </xsl:variable> 
     <xsl:variable name="textAll"> 
      <xsl:value-of select="text()"/> 
     </xsl:variable> 
     <xsl:variable name="textOnly"> 
      <xsl:choose> 
       <xsl:when test="contains($textAll,'.')"> 
        <xsl:value-of select="substring($textAll,1,string-length(substring-before($textAll,'.'))-1)"/> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:value-of select="text()"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:variable> 
     <xsl:variable name="textAll1"> 
      <xsl:value-of select="text()"/> 
     </xsl:variable> 
     <xsl:variable name="numbersOnly"> 
      <xsl:choose> 
       <xsl:when test="contains($textAll1,'.')"> 
        <xsl:value-of select="substring($textAll1,string-length($textOnly))"/> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:variable> 
     <div class="{$tertClassTypName}"> 
      <xsl:value-of select="$textOnly"/> 
      <xsl:call-template name="numbersToLink"> 
       <xsl:with-param name="numbersString" select="$numbersOnly"/> 
      </xsl:call-template> 
     </div> 
    </xsl:template> 

    <xsl:template match="content-style" name="content-style"> 
     <xsl:variable name="fontStyle"> 
      <xsl:value-of select="concat('font-style-',@font-style)"/> 
     </xsl:variable> 
     <span class="{$fontStyle}"> 
      <!--  <xsl:choose> 
<xsl:when test="matches(.,".*\d\.\d+-\d\.\d+.*")"> 
</xsl:when> 
     </xsl:choose> 
--> 
<xsl:variable name="textAll"> 
       <xsl:value-of select="../text()"/> 
      </xsl:variable> 
      <xsl:choose> 
       <xsl:when test="contains($textAll, '.')"> 

      <xsl:variable name="textOnly"> 
       <xsl:choose> 
        <xsl:when test="contains($textAll,'.')"> 
         <xsl:value-of select="substring($textAll,1,string-length(substring-before($textAll,'.'))-1)"/> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:value-of select="text()"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:variable> 
      <xsl:variable name="numbersOnly"> 
       <xsl:choose> 
        <xsl:when test="contains($textAll,'.')"> 
         <xsl:value-of select="substring($textAll,string-length($textOnly))"/> 
        </xsl:when> 
       </xsl:choose> 
      </xsl:variable> 
          <xsl:value-of select="$textOnly"/> 
       <xsl:call-template name="numbersToLink"> 
        <xsl:with-param name="numbersString" select="$numbersOnly"/> 
       </xsl:call-template> 

       </xsl:when> 

      <xsl:otherwise> 
         <xsl:apply-templates/> 
      </xsl:otherwise> 
      </xsl:choose> 


     </span> 
    </xsl:template> 

    <xsl:template name="numbersToLink"> 
     <xsl:param name="numbersString"/> 
     <xsl:choose> 
      <xsl:when test="contains($numbersString, ',')"> 
       <xsl:call-template name="splitByComma"> 
        <xsl:with-param name="numString" select="$numbersString"/> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:when test="contains($numbersString, '-')"> 
       <xsl:call-template name="splitByHyphen"> 
        <xsl:with-param name="numString" select="$numbersString"/> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:when test="5 >= string-length(normalize-space($numbersString))"> 
       <xsl:variable name="x"> 
        <xsl:value-of select="substring-after($numbersString,'.')"/> 
       </xsl:variable> 
       <xsl:variable name="y"> 
        <xsl:value-of select="normalize-space(substring-before($numbersString,'.'))"/> 
       </xsl:variable> 
       <!-- er:#BVI_CH_07/P7-251--> 
       <xsl:variable name="conca"> 
        <xsl:value-of select="concat('er:#BVI_CH_0',$y,'/P',$y,'-',$x)"/> 
       </xsl:variable> 
       <a href="{$conca}"> 
        <xsl:value-of select="$numbersString"/> 
       </a> 
      </xsl:when> 
      <xsl:otherwise> 

      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
    <xsl:template name="splitByComma"> 
     <xsl:param name="numString"/> 
     <xsl:choose> 
      <xsl:when test="contains(substring-before($numString,','), '-')"> 
       <xsl:call-template name="splitByHyphen"> 
        <xsl:with-param name="numString" select="$numString"/> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:when test="contains($numString,',')"> 
       <xsl:variable name="abc"> 
        <xsl:value-of select="normalize-space(substring-before($numString,'.'))"/> 
       </xsl:variable> 
       <xsl:variable name="def"> 
        <xsl:value-of select="substring-before(substring-after($numString,'.'),',') "/> 
       </xsl:variable> 
       <xsl:variable name="conct"> 
        <xsl:value-of select="concat('er:#BVI_CH_0',$abc,'/P',$abc,'-',$def)"/> 
        <!--"concat(concat('er:#BVI_CH_0',,'/P',$y,'-',$x)"/--> 
       </xsl:variable> 
       <a href="{$conct}"> 
        <xsl:value-of select="substring-before($numString,',')"/> 
       </a> 
       <xsl:text>, </xsl:text> 
       <xsl:if test="contains(substring-after($numString,','), '.')"> 
        <xsl:call-template name="numbersToLink"> 
         <xsl:with-param name="numbersString" select="normalize-space(substring-after($numString,','))"/> 
        </xsl:call-template> 
       </xsl:if> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:template> 
    <xsl:template name="splitByHyphen"> 
     <xsl:param name="numString"/> 
     <xsl:choose> 
      <xsl:when test="contains($numString,'-')"> 
       <xsl:variable name="abc"> 
        <xsl:value-of select="normalize-space(substring-before($numString,'.'))"/> 
       </xsl:variable> 
       <xsl:variable name="def"> 
        <xsl:value-of select="substring-before(substring-after($numString,'.'),'-') "/> 
       </xsl:variable> 
       <xsl:variable name="conct"> 
        <xsl:value-of select="concat('er:#BVI_CH_0',$abc,'/P',$abc,'-',$def)"/> 
        <!--"concat(concat('er:#BVI_CH_0',,'/P',$y,'-',$x)"/--> 
       </xsl:variable> 
       <a href="{$conct}"> 
        <!--<xsl:value-of select="substring-before($numString,'-')"/>--> 
        <xsl:value-of select="substring-before($numString,'-')"/> 
       </a> 
       <xsl:text>&#x2013;</xsl:text> 
       <xsl:if test="contains(substring-after($numString,'-'), '.')"> 
        <xsl:call-template name="numbersToLink"> 
         <xsl:with-param name="numbersString" select="normalize-space(substring-after($numString,'-'))"/> 
        </xsl:call-template> 
       </xsl:if> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

當我在Altova XMLSpy中使用我的XML表格。它沒有給出任何錯誤。但是當我用其他xml編輯器(氧氣和液體xml)時,它會拋出下面的錯誤。

Severity: error 
Description: A sequence of more than one item is not allowed as the first argument of contains() ("", "") 
Start location: 56:0 
URL: http://www.w3.org/TR/xpath20/#ERRXPTY0004 

請讓我知道爲什麼會發生這種情況,我該如何解決?

謝謝。

回答

3

哪一行確切導致該錯誤? XML輸入是怎麼看的?

Altova的被稱爲剝離空白文本節點,如果你想與撒克遜相同的行爲再加入

<xsl:strip-space elements="*"/> 

xsl:stylesheet元素的子元素。這可能會解決這個問題,假設錯誤是由於嘗試選擇文本內容text()而導致的,該文件包含帶有Saxon的空白文本節點,這些文本節點會被Altova剝離。

但一般來說,我會避免使用text().(依靠函數參數的霧化傳遞的功能,如contains時),只需選擇字符串內容或做string(.)明確。

+0

喜@馬丁同樣的效果的非常低效冗長的方式:這個工作謝謝 – 2013-03-27 08:32:21

3

線56是這樣的:

錯誤意味着當前節點(primaryie元件)具有多於一個文本子節點。也許其中一些是空白文本節點 - Altova使用Microsoft XML解析器,默認情況下會剝離空白文本節點。很難知道你應該用什麼替換它,而不知道你的應用程序,但它應該是test="contains(., '.')"

順便說一下,樣式表中有一些錯誤的代碼。這個:

<xsl:value-of select="index/title/@text()"/> 

選擇屬性軸上的所有文本節點。在屬性軸上將不會有任何文本節點,儘管要求它們是合法的。你的樣式也使得頻繁使用的結構

<xsl:variable name="tertClassType"> 
    <xsl:value-of select="@level"/> 
</xsl:variable> 

這是越來越爲

<xsl:variable name="tertClassType" select="@level"/> 
相關問題