在 <xsl:attribute 中包含 HTML 节点>



我想在元素的属性中包含HTML(对于此处使用的数据清除属性:http://foundation.zurb.com/docs/components/clearing.html)。我的<caption>数据有两种可用方式:

<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<caption>节点中的<a>标签与以下模板匹配:

<!-- 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>标记,但当我在<img> <xsl:attribute>中使用xsl:copy-of时,它会丢失。它将在属性外显示精细,如下所示:

<![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.]]>;" />

感谢阅读。

首先,让我们明确您的属性中没有包含"节点";您想要的是序列化包含XML标记的属性。我们谈论的是词汇层面,而不是树层面,节点只存在于树层面。

要产生这种输出,有两个挑战。首先,您需要构造一个包含词法XML的字符串,然后将该字符串作为属性的值传递。其次,您需要防止这个字符串中的特殊字符被转义。

对于第一个问题,有两种方法:您可以调用一个外部serialize()函数,该函数将树转换为字符串形式的词法XML,例如saxon:serialize(如果您使用的是saxon:serialize),或者您可以编写自己的函数(这对于简单的情况来说并不困难,而且已经完成了-David Carlisle已经用XSLT编写了一个完整的XML序列化程序)。

第二个问题很棘手。XSLT序列化规范(所有版本)坚持HTML序列化方法不应转义出现在属性值中的"<",但它对">"几乎没有什么可说的。Saxon将">"转义为"&gt;",表面上是因为这是较旧的浏览器所需要的(现在可能已经很旧了!),但我认为规范不需要这一点,其他处理器可能会有所不同。禁用输出转义对属性值无效,因此您可能不得不使用禁用输出转义手动构建整个元素序列化。或者,使用XSLT2.0,您可以使用字符映射来强制输出属性值中的">"。

在示例代码中,在编写变量值时使用禁用输出转义。规范中有关于这一点的yoyo历史。XSLT1.0的一个勘误表(所谓的"粘性doe"勘误表)说这是允许的,但在XSLT2.0中却被推翻了,因为它与允许对变量中的结果树片段进行完全导航访问不兼容。因此,底线是,它可能工作,也可能不工作,这取决于您使用的处理器——当然,通常禁用输出转义也是如此。

对于这个需求,一个完全不同的解决方案可能是输出一些不同的东西——例如使用V形代替尖括号——然后通过文本过滤器过滤序列化的输出,该过滤器将相关字符替换为您实际想要的字符。

相关内容

  • 没有找到相关文章

最新更新