13

更新:私はこの質問への回答を追加しました。これには、与えられたほとんどすべての提案が組み込まれています。以下のコードに示されている元のテンプレートは、実際の入力ドキュメント(スクリプトプログラミングに関する英語のテキスト)を完成させるために45605msを必要としました。コミュニティウィキの回答の改訂されたテンプレートにより、実行時間が605ミリ秒に短縮されました

次のXSLTテンプレートを使用して、文字列内のいくつかの特殊文字をエスケープされたバリアントに置き換えています。分割統治法を使用して再帰的に呼び出し、最終的には特定の文字列内のすべての文字を調べます。次に、文字をそのまま印刷するかどうか、または何らかの形式のエスケープが必要かどうかを決定します。

<xsl:template name="escape-text">
<xsl:param name="s" select="."/>
<xsl:param name="len" select="string-length($s)"/>
<xsl:choose>
    <xsl:when test="$len >= 2">
        <xsl:variable name="halflen" select="round($len div 2)"/>
        <xsl:variable name="left">
            <xsl:call-template name="escape-text">
                <xsl:with-param name="s" select="substring($s, 1, $halflen)"/>
                <xsl:with-param name="len" select="$halflen"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="right">
            <xsl:call-template name="escape-text">
                <xsl:with-param name="s" select="substring($s, $halflen + 1)"/>
                <xsl:with-param name="len" select="$halflen"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="concat($left, $right)"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:choose>
            <xsl:when test="$s = '&quot;'">
                <xsl:text>&quot;\&quot;&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '@'">
                <xsl:text>&quot;@&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '|'">
                <xsl:text>&quot;|&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '#'">
                <xsl:text>&quot;#&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '\'">
                <xsl:text>&quot;\\&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '}'">
                <xsl:text>&quot;}&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '&amp;'">
                <xsl:text>&quot;&amp;&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '^'">
                <xsl:text>&quot;^&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '~'">
                <xsl:text>&quot;~&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '/'">
                <xsl:text>&quot;/&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '{'">
                <xsl:text>&quot;{&quot;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$s"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

このテンプレートは、XSLTスクリプトが必要とするランタイムの大部分を占めています。上記のescape-textテンプレートを

<xsl:template name="escape-text">
    <xsl:param name="s" select="."/>
    <xsl:value-of select="$s"/>
</xsl:template>

XSLTスクリプトの実行時間が、ドキュメントの1つで45秒から1秒未満になります。

したがって、私の質問:escape-textテンプレートを高速化するにはどうすればよいですか?私はxsltprocを使用しており、純粋なXSLT1.0ソリューションを好みます。XSLT2.0ソリューションも歓迎されます。ただし、外部ライブラリはこのプロジェクトには役立たない可能性があります。それでも、外部ライブラリを使用するソリューションには興味があります。

4

8 に答える 8

16

別の(補完的な)戦略は、条件translate($s, $vChars, '') = $sが真の場合、文字列の長さが1になる前に、再帰を早期に終了することです。これにより、特殊文字をまったく含まない文字列の処理がはるかに高速になります。これはおそらくそれらの大部分です。もちろん、結果はxsltprocの実装がどれほど効率的かによって異なりますtranslate()

于 2010-08-24T20:38:56.977 に答える
7

非常に小さな修正で、テストの速度が約17倍向上しました

追加の改善点がありますが、今のところこれで十分だと思います... :)

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vChars">"@|#\}&amp;^~/{</xsl:variable>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="text()" name="escape-text">
  <xsl:param name="s" select="."/>
  <xsl:param name="len" select="string-length($s)"/>

  <xsl:choose>
    <xsl:when test="$len >= 2">
        <xsl:variable name="halflen" select="round($len div 2)"/>
        <xsl:variable name="left">
            <xsl:call-template name="escape-text">
                <xsl:with-param name="s" select="substring($s, 1, $halflen)"/>
                <xsl:with-param name="len" select="$halflen"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="right">
            <xsl:call-template name="escape-text">
                <xsl:with-param name="s" select="substring($s, $halflen + 1)"/>
                <xsl:with-param name="len" select="$halflen"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="concat($left, $right)"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:choose>
            <xsl:when test="not(contains($vChars, $s))">
             <xsl:value-of select="$s"/>
            </xsl:when>
            <xsl:when test="$s = '&quot;'">
                <xsl:text>&quot;\&quot;&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '@'">
                <xsl:text>&quot;@&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '|'">
                <xsl:text>&quot;|&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '#'">
                <xsl:text>&quot;#&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '\'">
                <xsl:text>&quot;\\&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '}'">
                <xsl:text>&quot;}&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '&amp;'">
                <xsl:text>&quot;&amp;&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '^'">
                <xsl:text>&quot;^&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '~'">
                <xsl:text>&quot;~&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '/'">
                <xsl:text>&quot;/&quot;</xsl:text>
            </xsl:when>
            <xsl:when test="$s = '{'">
                <xsl:text>&quot;{&quot;</xsl:text>
            </xsl:when>
        </xsl:choose>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
于 2010-08-24T16:59:42.243 に答える
4

@Dimitreの回答に基づいて、より改善されたバージョンを次に示します。

  <xsl:template match="text()" name="escape-text">
    <xsl:param name="s" select="."/>
    <xsl:param name="len" select="string-length($s)"/>

    <xsl:choose>
      <xsl:when test="$len &gt; 1">
        <xsl:variable name="halflen" select="round($len div 2)"/>
        <!-- no "left" and "right" variables necessary! -->
        <xsl:call-template name="escape-text">
          <xsl:with-param name="s" select="substring($s, 1, $halflen)"/>
        </xsl:call-template>
        <xsl:call-template name="escape-text">
          <xsl:with-param name="s" select="substring($s, $halflen + 1)"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="not(contains($vChars, $s))">
            <xsl:value-of select="$s"/>
          </xsl:when>
          <xsl:when test="contains('\&quot;', $s)">
            <xsl:value-of select="concat('&quot;\', $s, '&quot;')" />
          </xsl:when>
          <!-- all other cases can be collapsed, this saves some time -->
          <xsl:otherwise>
            <xsl:value-of select="concat('&quot;', $s, '&quot;')" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

もう少し速いはずですが、私はそれをベンチマークしていません。いずれにせよ、それは短いです。;-)

于 2010-08-24T18:52:23.327 に答える
3

価値のあるものとして、これが私の現在のバージョンのescape-textテンプレートであり、私の質問に答えて人々が与えた(優れた!)提案のほとんどが組み込まれています。ちなみに、私の元のバージョンは、サンプルのDocBookドキュメントで平均約45605msかかりました。その後、実行時間は複数のステップで短縮されました。

  • 呼び出しとともにleftand変数を削除すると、実行時間が13052msに短縮されました。この最適化は、Tomalakの回答から取得されました。rightconcat()
  • 一般的なケース(つまり、指定された文字は特別なエスケープを必要としません)を最初に内側の<xsl:choose>要素に移動すると、ランタイムがさらに5812ミリ秒に短縮されました。この最適化は、Dimitreによって最初に提案されました
  • 指定された文字列に特殊文字が含まれているかどうかを最初にテストして再帰を早期に中止すると、実行時間が612msに短縮されました。この最適化はMichaelによって提案されました
  • 最後に、 Tomalakの回答でDimitreによるコメントを読んだ後、マイクロ最適化を行うことに抵抗できませんでした。<xsl:value-of select="concat('x', $s, 'y')"/>呼び出しをに置き換えました<xsl:text>x</xsl:text><xsl:value-of select="$s"/><xsl:text>y</xsl:text>。これにより、ランタイムは約606msになりました(つまり、約1%の改善)。

最終的に、関数は45605msではなく606msかかりました。印象的!

<xsl:variable name="specialLoutChars">"@|#\}&amp;^~/{</xsl:variable>

<xsl:template name="escape-text">
    <xsl:param name="s" select="."/>
    <xsl:param name="len" select="string-length($s)"/>
    <xsl:choose>
        <!-- Common case optimization: 
             no need to recurse if there are no special characters -->
        <xsl:when test="translate($s, $specialLoutChars, '') = $s">
            <xsl:value-of select="$s"/>
        </xsl:when>
        <!-- String length greater than 1, use DVC pattern -->
        <xsl:when test="$len > 1">
            <xsl:variable name="halflen" select="round($len div 2)"/>
            <xsl:call-template name="escape-text">
                <xsl:with-param name="s" select="substring($s, 1, $halflen)"/>
                <xsl:with-param name="len" select="$halflen"/>
            </xsl:call-template>
            <xsl:call-template name="escape-text">
                <xsl:with-param name="s" select="substring($s, $halflen + 1)"/>
                <xsl:with-param name="len" select="$len - $halflen"/>
            </xsl:call-template>
        </xsl:when>
        <!-- Special character -->
        <xsl:otherwise>
            <xsl:text>&quot;</xsl:text>
            <!-- Backslash and quot need backslash escape -->
            <xsl:if test="$s = '&quot;' or $s = '\'">
                <xsl:text>\</xsl:text>
            </xsl:if>
            <xsl:value-of select="$s"/>
            <xsl:text>&quot;</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
于 2010-08-24T21:19:30.857 に答える
1

EXSLTを使ってみませんか?EXSLTのString関数には、 replaceと呼ばれる関数があります。これは、かなりの数のXSLT実装でサポートされているものだと思います。

于 2010-08-24T17:56:41.387 に答える
1

更新:これを実際に機能するように修正しました。今、それはスピードアップではありません!

@Wilfredの答えを構築しています...

EXSLT replace()関数をいじった後、OPにとって役に立たない場合でも、別の回答を投稿するのは十分に興味深いと思いました。それは他の人にも役立つかもしれません。

アルゴリズムのおかげで興味深いです:ここで作業したメインアルゴリズムの代わりに(バイナリ再帰検索を実行し、各再帰で半分に分割し、2 ^ n番目のサブ文字列に特殊文字が含まれていない場合は常に削除し、特殊文字の選択を繰り返します長さ=1の文字列に特殊文字が含まれている場合の文字)、Jeni TennisonのEXSLTアルゴリズムは、外側のループにある一連の検索文字列に対して反復を行います。したがって、ループの内側では、一度に1つの文字列のみを検索し、盲目的に半分に分割する代わりに、substring-before()/ substring-after()を使用して文字列を分割できます。

[非推奨:大幅に高速化するにはこれで十分だと思います。私のテストでは、 @ Dimitreの最新のものより2.94倍高速化されていることが示されています(平均230ms対676ms)。]OxygenXMLプロファイラーでSaxon6.5.5を使用してテストしていました。入力として、 JavaScriptに関するWebページ から作成されたほとんどが単一のテキストノードである7MBのXMLドキュメントを繰り返し使用しました。それはOPが最適化しようとしていたタスクの代表であるように私には聞こえます。他の人がテストデータと環境でどのような結果を得るのかを聞いてみたいと思います。

依存関係

これは、exsl:node-set()に依存するreplaceのXSLT実装を使用します。xsltprocがこの拡張機能(おそらくそれの初期バージョン)をサポートしているようです。したがって、これはすぐに使用できる可能性があります、@ Frerich; Saxonの場合と同様に、他のプロセッサの場合。

ただし、100%純粋なXSLT 1.0が必要な場合は、2番目と3番目のパラメーターがRTFではなくノードセットとして渡される限り、exsl:node-set()なしで機能するようにこの置換テンプレートを変更するのはそれほど難しくないと思います。 。

これが私が使用したコードで、置換テンプレートを呼び出します。長さの大部分は、検索/置換ノードセットを作成した詳細な方法で占められています...おそらく短縮される可能性があります。(ただし、置換テンプレートが現在作成されているため、ノード属性の検索または置換を行うことはできません。ドキュメント要素の下に属性を配置しようとするとエラーが発生します。)

<xsl:stylesheet version="1.0" xmlns:str="http://exslt.org/strings"
    xmlns:foo="http://www.foo.net/something" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:import href="lars.replace.template.xsl"/>

    <foo:replacements>
        <replacement>
            <search>"</search>
            <replace>"\""</replace>
        </replacement>
        <replacement>
            <search>\</search>
            <replace>"\\"</replace>
        </replacement>
        <replacement>
            <search>@</search>
            <replace>"["</replace>
        </replacement>
        <replacement>
            <search>|</search>
            <replace>"["</replace>
        </replacement>
        <replacement>
            <search>#</search>
            <replace>"["</replace>
        </replacement>
        <replacement>
            <search>}</search>
            <replace>"}"</replace>
        </replacement>
        <replacement>
            <search>&amp;</search>
            <replace>"&amp;"</replace>
        </replacement>
        <replacement>
            <search>^</search>
            <replace>"^"</replace>
        </replacement>
        <replacement>
            <search>~</search>
            <replace>"~"</replace>
        </replacement>
        <replacement>
            <search>/</search>
            <replace>"/"</replace>
        </replacement>
        <replacement>
            <search>{</search>
            <replace>"{"</replace>
        </replacement>
    </foo:replacements>

    <xsl:template name="escape-text" match="text()" priority="2">
        <xsl:call-template name="str:replace">
            <xsl:with-param name="string" select="."/>
            <xsl:with-param name="search"
                select="document('')/*/foo:replacements/replacement/search/text()"/>
            <xsl:with-param name="replace"
                select="document('')/*/foo:replacements/replacement/replace/text()"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

インポートされたスタイルシートは元々これでした。

ただし、@ Frerichが指摘したように、正しい出力が得られることはありませんでした。それは私に、正確さをチェックせずにパフォーマンスの数字を投稿しないように教えてくれるはずです!

デバッガーで問題が発生していることはわかりますが、EXSLTテンプレートが機能しなかったのか、Saxon6.5.5で機能しなかったのかはわかりません...どちらのオプションも驚くべきことです。

いずれにせよ、EXSLTのstr:replace()は必要以上のことをするように指定されているので、次のように変更しました。

  • 入力パラメータがすでにノードセットである必要があります
  • 結果として、exsl:node-set()は必要ありません
  • 検索文字列を長さで並べ替えないでください(このアプリケーションでは、すべて1文字です)
  • 対応する検索文字列が空の場合、文字のすべてのペアの間に置換文字列を挿入しないでください

変更された置換テンプレートは次のとおりです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:str="http://exslt.org/strings">
   <!-- By Lars Huttar
    based on implementation of EXSL str:replace() by Jenni Tennison.
    http://www.exslt.org/str/functions/replace/str.replace.template.xsl
    Modified by Lars not to need exsl:node-set(), not to bother sorting
    search strings by length (in our application, all the search strings are of
    length 1), and not to put replacements between every other character
    when a search string is length zero.
    Search and replace parameters must both be nodesets.
    -->

   <xsl:template name="str:replace">
      <xsl:param name="string" select="''" />
      <xsl:param name="search" select="/.." />
      <xsl:param name="replace" select="/.." />
      <xsl:choose>
         <xsl:when test="not($string)" />
         <xsl:when test="not($search)">
            <xsl:value-of select="$string" />
         </xsl:when>
         <xsl:otherwise>
            <xsl:variable name="search1" select="$search[1]" />
            <xsl:variable name="replace1" select="$replace[1]" />

            <xsl:choose>
               <xsl:when test="contains($string, $search1)">
                  <xsl:call-template name="str:replace">
                     <xsl:with-param name="string"
                        select="substring-before($string, $search1)" />
                     <xsl:with-param name="search"
                        select="$search[position() > 1]" />
                     <xsl:with-param name="replace"
                        select="$replace[position() > 1]" />
                  </xsl:call-template>
                  <xsl:value-of select="$replace1" />
                  <xsl:call-template name="str:replace">
                     <xsl:with-param name="string"
                        select="substring-after($string, $search)" />
                     <xsl:with-param name="search" select="$search" />
                     <xsl:with-param name="replace" select="$replace" />
                  </xsl:call-template>
               </xsl:when>
               <xsl:otherwise>
                  <xsl:call-template name="str:replace">
                     <xsl:with-param name="string" select="$string" />
                     <xsl:with-param name="search"
                        select="$search[position() > 1]" />
                     <xsl:with-param name="replace"
                        select="$replace[position() > 1]" />
                  </xsl:call-template>
               </xsl:otherwise>
            </xsl:choose>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

</xsl:stylesheet>

この単純なテンプレートの副次的な利点の1つは、検索のノードの属性を使用してパラメーターを置き換えることができることです。これにより、<foo:replacements>データがよりコンパクトになり、IMOが読みやすくなります。

パフォーマンス:この改訂されたテンプレートを使用すると、作業は約2.5秒で完了しますが、主要な競合他社である@DimitreのXSLT1.0スタイルシートの最近のテストでは0.68秒で完了します。したがって、スピードアップではありません。しかし、繰り返しになりますが、他の人は私とは非常に異なるテスト結果を持っているので、他の人がこのスタイルシートで何を得るのか聞きたいです。

于 2010-08-26T02:52:21.040 に答える
0

OK、チップインします。XSLT1.0バージョンの最適化ほど面白くはありませんが、XSLT 2.0ソリューションは歓迎されるとおっしゃっていたので、ここに私のものがあります。

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

    <xsl:template name="escape-text" match="text()" priority="2">
        <xsl:variable name="regex1">[@|#}&amp;^~/{]</xsl:variable>
        <xsl:variable name="replace1">"$0"</xsl:variable>
        <xsl:variable name="regex2">["\\]</xsl:variable>
        <xsl:variable name="replace2">"\\$0"</xsl:variable>
        <xsl:value-of select='replace(replace(., $regex2, $replace2),
                              $regex1, $replace1)'/>
    </xsl:template>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

これは、正規表現replace()を使用して、\または"をそれぞれ"\"または"\""に置き換えます。他のエスケープ可能な文字を引用符で囲むために、別のregexp replace()で構成されます。

私のテストでは、これはDimitreの最新のXSLT 1.0製品よりも2倍以上パフォーマンスが悪いです(しかし、私は自分のテストデータを作成しました、そして他の条件は特異であるかもしれないので、他の結果がどうなるか知りたいです得る。)

なぜパフォーマンスが遅いのですか?正規表現の検索は固定文字列の検索よりも遅いためだと推測できます。

更新: analyze-stringを使用

@Alejandroの提案によると、ここではanalyze-stringを使用しています。

<xsl:template name="escape-text" match="text()" priority="2">
    <xsl:analyze-string select="." regex='([@|#}}&amp;^~/{{])|(["\\])'>
        <xsl:matching-substring>
            <xsl:choose>
                <xsl:when test="regex-group(1)">"<xsl:value-of select="."/>"</xsl:when>
                <xsl:otherwise>"\<xsl:value-of select="."/>"</xsl:otherwise>
            </xsl:choose>
        </xsl:matching-substring>
        <xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
    </xsl:analyze-string>
</xsl:template>

これは良い考えのように思えますが、残念ながらパフォーマンスを向上させることはできません。私のセットアップでは、上記のreplace()テンプレートの場合は1〜1.4秒であるのに対し、私のセットアップでは、完了するのに一貫して約14秒かかります。それを10-14倍の減速と呼んでください。:-(これは、XSLTレベルで大量の大きな文字列を分割して連結する方が、組み込み関数で大きな文字列を2回トラバースするよりもはるかにコストがかかることを示唆しています。

于 2010-08-25T19:27:04.393 に答える
0

@ Frerich-Raabeがコミュニティウィキの回答を公開した後、これまでの提案を組み合わせて、(彼のデータで)76倍のスピードアップを達成しました-皆さん、おめでとうございます!!!

私はそれ以上進まないことに抵抗できませんでした:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:variable name="specialLoutChars">"@|#\}&amp;^~/{</xsl:variable>

 <xsl:key name="kTextBySpecChars" match="text()"
  use="string-length(translate(., '&quot;@|#\}&amp;^~/', '') = string-length(.))"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="text()[key('kTextBySpecChars', 'true')]" name="escape-text">
  <xsl:param name="s" select="."/>
  <xsl:param name="len" select="string-length($s)"/>

  <xsl:choose>
    <xsl:when test="$len >= 2">
        <xsl:variable name="halflen" select="round($len div 2)"/>
        <xsl:call-template name="escape-text">
            <xsl:with-param name="s" select="substring($s, 1, $halflen)"/>
            <xsl:with-param name="len" select="$halflen"/>
        </xsl:call-template>
        <xsl:call-template name="escape-text">
            <xsl:with-param name="s" select="substring($s, $halflen + 1)"/>
            <xsl:with-param name="len" select="$len - $halflen"/>
        </xsl:call-template>
    </xsl:when>
    <xsl:when test="$len = 1">
        <xsl:choose>
            <!-- Common case: the character at hand needs no escaping at all -->
            <xsl:when test="not(contains($specialLoutChars, $s))">
                <xsl:value-of select="$s"/>
            </xsl:when>
            <xsl:when test="$s = '&quot;' or $s = '\'">
                <xsl:text>&quot;\</xsl:text>
                <xsl:value-of select="$s"/>
                <xsl:text>&quot;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>&quot;</xsl:text>
                <xsl:value-of select="$s"/>
                <xsl:text>&quot;</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:when>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

この変換により、(私のデータでは)さらに1.5倍のスピードアップが達成されます。したがって、全体のスピードアップは100倍以上になるはずです。

于 2010-08-24T21:39:02.767 に答える