2013-03-26 5 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> 

저는 이것을 XML 문서의 Altova XMLSpy에서 사용하고 있습니다. 어떤 오류도주지 않습니다. 하지만 다른 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 입력은 어떻게 보이나요? 당신은 색슨 족과 같은 동작은 다음 xsl:stylesheet 요소의 자식으로

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

를 추가하려면

Altova은 공백 텍스트 노드를 제거하는 것으로 알려져있다. 그 오류는 text()으로 텍스트 내용을 선택하려는 시도로 인해 오류가 발생했다고 가정하고 Altova로 제거 된 Saxon이있는 공백 텍스트 노드를 포함합니다.

그러나 일반적으로 내가 text()를 사용하지 않는 것이며 (contains 같은 기능에 전달 때 함수 인수의 분무에 의존) 단순히 .와 문자열 내용을 선택하거나 명시 적으로 string(.)을한다.

+0

안녕 @Martin와 같은 효과를 얻기의 몹시 비효율적이고 자세한 방법입니다 구조

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

자주 사용한다 :이 덕분에 일 –

3

라인 (56)이있다 :

오류가 현재 노드 (a primaryie 소자)가 하나 이상의 텍스트 노드의 자식을 갖는 것을 의미한다. 아마도 이들 중 일부는 공백 텍스트 노드입니다. Altova는 기본적으로 공백 텍스트 노드를 제거하는 Microsoft XML 파서를 사용합니다. 신청서를 모른 채로 무엇을 대체 할지를 아는 것은 어렵지만 아마도 test="contains(., '.')"이어야합니다.

덧붙여서, 스타일 시트에 나쁜 코드가 있습니다. 이것은

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

은 속성 축의 모든 텍스트 노드를 선택합니다. 속성 축에는 아무 텍스트 노드도 존재하지 않지만, 요청할 수는 있습니다. 스타일 시트는

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