【问题标题】:How to generate markup inside of <xsl:attribute> text?如何在 <xsl:attribute> 文本中生成标记?
【发布时间】:2015-04-08 12:52:08
【问题描述】:

我的 XSLT 样式表生成 Bootstrap HTML,其中一些元素可能包含 data-... 属性以将额外数据传递给框架。例如,我有这个代码来生成一个popover 元素:

<xsl:template match="foo">
  <a href="#" data-toggle="popover" data-placement="top" data-trigger="hover" data-html="true">
    <xsl:attribute name="title">Popover Title</xsl:attribute>
    <xsl:attribute name="data-content">This is some additional content.</xsl:attribute>
    <xsl:text>Link</xsl:text>
  </a>
</xsl:template>

data-content 属性应该包含额外的标记。结果输出应该类似于

<a href="#" ... data-content="This is <em>some</em> additional <a href='#'>content</a>.">Link</a>

在这种情况下如何为&lt;xsl:attribute&gt; 生成标记文本?

(有些相关:hereherehere。)

答案

感谢您的回答!虽然我认为kjhughes's answer 提供了技术上正确的解决方案来正确实施我需要的东西,但我认为Ian's answer 更直接地解决了我的问题。

【问题讨论】:

  • 我认为在属性值中不允许使用非转义标记,是吗?如果您的输出是 XML,那肯定不是。
  • 对,不是。见details below

标签: xslt


【解决方案1】:

您不能将未转义的标记放在属性值中,但是you don't need to - 如果您将尖括号(以及任何与号和引号内的引号)作为实体引用,引导程序仍将在弹出窗口中正确呈现 html .

<a href="#" data-content="This is &lt;em&gt;some&lt;/em&gt; additional &lt;a href='#'&gt;content&lt;/a&gt;.">Link</a>

在 XSLT 中实现这一点的最简单方法是使用 CDATA 部分:

<xsl:attribute name="data-content"
  ><![CDATA[This is <em>some</em> additional content
    &amp; a <a href="#">link</a>.]]></xsl:attribute>

序列化程序会根据需要为您转义它。

【讨论】:

  • 有趣的是,小提琴部分工作:&lt;em&gt; 不显示,但 &lt;a&gt; 显示。
  • @Jens 确实如此,我尝试将 em 更改为 strong 并且确实显示为粗体,因此它似乎只是某些标签。或者可能是引导程序的 css 中的东西。
  • @Jens 好的,这是 jsfiddle 的错 - here's a version with "normalize css" unticked 按预期呈现 em
  • 为了让它更时髦一点,我可以使用几个 CDATA 部分来包装其他 XSLT 元素。例如:&lt;xsl:attribute name="data-content"&gt;&lt;![CDATA[&lt;a href="#" id="]]&gt;popup-&lt;xsl:value-of select="@id"/&gt;&lt;![CDATA["&gt;Link&lt;/a&gt;]]&gt;&lt;/xsl:attribute&gt;
【解决方案2】:

您不能在 xsl:attribute 内生成标记,因为 XML 不允许在属性内进行非转义标记。

具体来说,AttValuegrammar rule 完全禁止&lt;&amp;,除非&amp; 是正确格式Reference 的一部分:

AttValue       ::=      '"' ([^<&"] | Reference)* '"'
                      | "'" ([^<&'] | Reference)* "'"

支持定义:

Reference      ::=      EntityRef | CharRef
EntityRef      ::=      '&' Name ';'
CharRef        ::=      '&#' [0-9]+ ';'
                      | '&#x' [0-9a-fA-F]+ ';'

HTML 也是如此,即使是HTML5,也不允许在属性值中使用非转义标记。

在属性值中添加转义标记是可行的,但很难看。特别是对于大量标记的内容,我建议单独创建内容,然后通过 JavaScript 以程序方式关联它,而不是通过属性值以声明方式关联。有很多这样做的例子,包括您的一篇参考资料中提到的this one

【讨论】:

  • 我相信 HTML 规范在这里更相关,因为这就是 OP 正在生成的内容:“属性值可能只包含字母(az 和 AZ)、数字(0-9)、连字符(ASCII 十进制 45)、句点(ASCII 十进制 46)、下划线(ASCII 十进制 95)和冒号(ASCII 十进制 58)。" w3.org/TR/html401/intro/sgmltut.html#h-3.2.2
  • @michael.hor257k:嗯。你是说Bootstrap对data-content属性的使用是无效的HTML?
  • @Jens 你能举个例子,他们在data-content 属性中使用标记吗?我在你链接的页面上没有看到。
  • @michael.hor257k:我刚刚添加了对其他三个问题的引用,所有这些问题都在该属性中嵌入了 HTML 示例(特别是 this 一个)。
  • @Jens,是的,我更喜欢您的第一个示例中的this approach,尤其是当您需要大量标记时。除了标记不属于 XML 或 HTML 的属性值之外,单独的 divs 更易于创建、阅读和编辑。
【解决方案3】:

这不是“官方”的方式,但是当使用lxml 处理 XML 和 XSLT 样式表时,请考虑在您的样式表中使用 XSLT extension elements。这些自定义元素允许您在处理过程中元素匹配时运行 Python 代码,并且该代码可以修改/编辑输出文档的部分内容。

【讨论】:

    猜你喜欢
    • 2019-01-25
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    相关资源
    最近更新 更多