1

要素の属性内に HTML を含めたい (ここで使用される data-clearing 属性: http://foundation.zurb.com/docs/components/clearing.html )。私の<caption>データは、次の 2 つの方法で利用できます。

<caption mode="formatted">
    <p>A fairly long looking <a href="http://www.stackoverflow.com">caption with a link</a> that goes to an external site.</p>
</caption>
<caption mode="unformatted">
    <![CDATA[A fairly long looking <a href="http://www.stackoverflow.com">caption with a link</a> that goes to an external site.]]>
</caption>

ここに私のテンプレートがあります:

<xsl:template match="images/entry">
    <!-- process contents of caption node-->
    <xsl:variable name="cap">
        <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
        <xsl:apply-templates select="caption/*" mode="html" />
        <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
    </xsl:variable>

    <li>
        <xsl:copy-of select="$cap"/> //outside of attribute it works
        <img>
            <xsl:attribute name="src">/image/2/150/112/5<xsl:value-of select="@path"/>/<xsl:value-of select="filename"/></xsl:attribute>
            <xsl:attribute name="data-caption">
                <xsl:copy-of select="$cap"/> //inside of attribute it removes the <a> tag
            </xsl:attribute>
        </img>
    </li>
</xsl:template>

は、ノード内のタグを次のテンプレートとmode=html照合します。<a><caption>

<!-- mark external links -->
<xsl:template match="a" mode="html">
<a href="{@href}" title="{@title}">
    <xsl:if test="number(substring(@href,1,4)='http')">
        <xsl:attribute name="class">external</xsl:attribute>
        <xsl:attribute name="target">_blank</xsl:attribute>
    </xsl:if>
    <xsl:apply-templates select="* | @* | text()" mode="html"/>
</a>
</xsl:template>

「フォーマットされていない」キャプションを使用すると、<a>タグが保持されます (望ましい動作)。ただし、そのキャプションを使用すると、「外部リンクをマーク」テンプレートを使用して<a>タグを修正できません。「フォーマットされた」キャプションを使用すると、<a>タグを好きなように処理できますが、xsl:copy-ofの中で使用すると失われ<img> <xsl:attribute>ます。次のように、属性の外側に問題なく表示されます。

<![CDATA[<p>A fairly long looking <a href="http://www.stackoverflow.com" title="" class="external" target="_blank">caption with a link</a> that goes to an external site.</p>]]>

最終結果を次のようにする方法はありますか:

<img src="/image/2/150/112/5/images/my-image.jpg" 
    data-caption="<![CDATA[A fairly long looking <a class="external" target="_blank" href="http://www.stackoverflow.com">caption with a link</a> that goes to an external site.]]>;" />

読んでくれてありがとう。

4

1 に答える 1

3

まず、属性に「ノード」を含めていないことを明確にしましょう。必要なのは、XML マークアップを含む属性をシリアル化することです。ツリー レベルではなくレキシカル レベルで話しているので、ノードはツリー レベルにしか存在しません。

この出力を生成するには、2 つの課題があります。まず、レキシカル XML を含む文字列を作成し、この文字列を属性の値として渡す必要があります。次に、この文字列内の特殊文字がエスケープされないようにする必要があります。

最初の問題については、2 つの方法があります。Saxon を使用している場合は saxon:serialize() のように、ツリーをレキシカル XML に文字列として変換する外部 serialize() 関数を呼び出す方法と、独自の (これは単純なケースでは難しくなく、すでに完了しています (David Carlisle が XSLT で完全な XML シリアライザーを作成しています)。

2 つ目の問題は厄介です。XSLT シリアライゼーション仕様 (すべてのバージョン) は、HTML シリアライゼーション メソッドが属性値に現れる "<" をエスケープしてはならないことを固く主張していますが、">" についてはほとんど、またはまったく言及していません。Saxon は ">" を としてエスケープし"&gt;"ますが、表向きはこれが古いブラウザ (おそらく今では非常に古いもの) で必要とされているためですが、これは仕様では必要ではないと思います。また、他のプロセッサでは異なる場合があります。Disable-output-escaping は属性値に対しては機能しないため、disable-output-escaping を使用して手動で要素のシリアル化全体を構築する必要がある場合があります。または、XSLT 2.0 では、文字マップを使用して、属性値で ">" を強制的に出力できます。

サンプル コードでは、変数の値を書き込むときに disable-output-escaping を使用しています。仕様にはヨーヨーの歴史があります。XSLT 1.0 の正誤表 (いわゆる「sticky doe」正誤表) では許可されているとされていましたが、変数に保持された結果ツリー フラグメントへの完全なナビゲーション アクセスを許可することと互換性がないため、これは XSLT 2.0 で取り消されました。要するに、使用するプロセッサに応じて機能する場合と機能しない場合がありますが、もちろん、それは一般的な disable-output-escaping にも当てはまります。

この要件に対する完全に異なる解決策は、たとえば山かっこの代わりにシェブロンを使用するなど、別のものを出力し、関連する文字を実際に必要な文字に置き換えるテキスト フィルターを介してシリアル化された出力をフィルター処理することです。

于 2013-09-05T08:10:55.687 に答える