0

私は以下の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>

AltovaXMLSpyの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

なぜこれが起こっているのか、どうすれば修正できますか?

ありがとう。

4

2 に答える 2

4

どの行がそのエラーを正確に引き起こしますか?そして、XML入力はどのように見えますか?

Altovaは空白のテキストノードを削除することが知られています。Saxonで同じ動作が必要な場合は、次を追加してください。

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

要素の子としてxsl:stylesheettext()エラーがテキストコンテンツを選択しようとしたために発生し、 Altovaで削除されたSaxonの空白テキストノードが含まれていると仮定すると、これで修正される可能性があります。

しかし、一般的にはtext()、文字列の内容を使用せずに選択するか.(およびのような関数に渡されるときに関数の引数のアトマイズに依存するcontains)、string(.)明示的に実行します。

于 2013-03-26T15:24:51.507 に答える
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"/>
于 2013-03-26T18:14:44.073 に答える