2

Visual Studio 2010でXSLを使用しています。次の * XSL * ファイルがあり、関数を使用して文字列を分割しようとしています:tokenize()

<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' >
<xsl:output media-type="text/html; charset=UTF-8" encoding="UTF-8"/>

<xsl:template match='/'>
    <html>
        <head> </head>
        <body>
            <ul>
                <xsl:apply-templates select="response/result/doc"/>
            </ul>
        </body>
    </html>
</xsl:template>

<xsl:template match="doc">
    <xsl:variable name="title" select="str[@name='Title']"/>
    <xsl:variable name="features" select="tokenize(str[@name='Desc'],';')"/>
    <li>
        <xsl:value-of select="$title"/>
        <ul>
            <xsl:for-each select="$features">
                <li>
                    <xsl:value-of select="."/>
                </li>
            </xsl:for-each>

        </ul>
    </li>
</xsl:template>
</xsl:stylesheet>

注:この時点で、実際にXSLT バージョン 2.0を使用しているかどうかはわかりません。最初の行に設定したからだと思います。

上記のXSLに対して、 Visual Studio 2010で次のエラーが発生します。

'tokenize()' is an unknown XSLT function.

次の入力XMLファイルがあります。

<?xml version="1.0" encoding="UTF-8"?>
<response>
<result name="response" numFound="10000" start="0">
    <doc>
        <str name="Title">Title 1</str>
        <str name="Desc">Feature 1; Feature 2; Feature 3;</str>
    </doc>
    <doc>
        <str name="Title">Title 2</str>
        <str name="Desc">Feature 1; Feature 2; Feature 3;</str>
    </doc>
</result>
 </response>

理想的には、以下のHTMLファイルのような出力が必要です。

<html>
<head> </head>
<body>
    <ul>
        <li>Title 1
            <ul>
                <li>Feature 1</li>
                <li>Feature 2</li>
                <li>Feature 3</li>
            </ul>
        </li>
        <li>Title 2
            <ul>
                <li>Feature 1</li>
                <li>Feature 2</li>
                <li>Feature 3</li>
            </ul>
        </li>
    </ul>
</body>
 </html>

XMLファイルでtokenize()文字列Descを分割するにはどうすればよいですか? この空白は無視してください。つまり、出力ファイルはHTMLであるため、出力ファイルの前後に余分なスペースがあっても意味がありません。

4

2 に答える 2

4

XSLT 2.0は、Visual Studio または .NET でネイティブにサポートされていません。XSLT 2.0 スタイルシートを実行しようとすると、2.0 関数を使用しようとするとエラーが発生します。

オプション #1:次のXSLT 1.0スタイルシートでは、再帰的なテンプレートを使用して、tokenize()関数を使用せずに同じ結果を実現しています。

<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' >
    <xsl:output media-type="text/html; charset=UTF-8" encoding="UTF-8"/>

    <xsl:template match='/'>
        <html>
            <head> </head>
            <body>
                <ul>
                    <xsl:apply-templates select="response/result/doc"/>
                </ul>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="doc">
        <li>
            <xsl:value-of select="str[@name='Title']"/>
            <ul>
                <xsl:call-template name="listItem">
                    <xsl:with-param name="features" select="str[@name='Desc']"/>
                </xsl:call-template>
            </ul>
        </li>
    </xsl:template>

    <xsl:template name="listItem">
        <xsl:param name="features"/>
        <xsl:param name="delimiter" select="';'"/>
        <xsl:choose>
            <xsl:when test="contains($features, $delimiter)">
                <li>
                    <xsl:value-of select="normalize-space(
                                            substring-before($features, $delimiter))"/>
                </li>
                <xsl:variable name="nextValue" select="substring-after($features, 
                                                                       $delimiter)"/>
                <xsl:if test="normalize-space($nextValue)">
                    <xsl:call-template name="listItem">
                        <xsl:with-param name="features" select="$nextValue"/>
                        <xsl:with-param name="delimiter" select="$delimiter"/>
                    </xsl:call-template>    
                </xsl:if>
            </xsl:when>
            <xsl:otherwise>
                <li>
                    <xsl:value-of select="$features"/>
                </li>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

オプション #2:また、Visual Studio で EXSLT.NET 参照を追加できる必要があり、その後、EXSLT str:tokenize() 関数を使用できるようになります。

<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' 
    xmlns:str="http://exslt.org/strings" >
    <xsl:output media-type="text/html; charset=UTF-8" encoding="UTF-8"/>

    <xsl:template match='/'>
        <html>
            <head> </head>
            <body>
                <ul>
                    <xsl:apply-templates select="response/result/doc"/>
                </ul>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="doc">
        <li>
            <xsl:value-of select="str[@name='Title']"/>
            <ul>
                <xsl:for-each select="str:tokenize(str[@name='Desc'], ';')">
                    <li>
                        <xsl:value-of select="normalize-space(.)"/>
                    </li>
                </xsl:for-each>
            </ul>
        </li>
    </xsl:template>
</xsl:stylesheet>
于 2013-06-28T02:34:38.363 に答える
1

スタイルシートが XSLT 2.0 環境を予期していることを最初の行で示していますが、エラー メッセージは XSLT 1.0 環境を使用していることを示しています。

于 2013-06-27T20:53:04.107 に答える