通过 XSLT 替换 XHTML 中的 style= 属性时出现不明确的规则匹配
这是此问题的后续问题。
我在文档中有几个 标记,其中有几个用分号分隔的样式属性。现在我有 3 个特定的样式属性,我正在寻找将其转换为标签。只要样式属性仅包含三个样式属性之一,在上面的示例中一切都可以正常工作。如果一个跨度有更多,我会得到一个不明确的规则匹配。
我正在寻找的三个样式属性是 font-style:italic
、font-weight:600
和 text-decoration:underline
应从样式属性中删除并分别转换为 、
和
。
这是我当前的 XSLT:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="span[
contains(translate(@style, ' ', ''), 'font-style:italic')
]">
<xsl:copy>
<xsl:attribute name="style">
<xsl:value-of select="substring-before(@style, ' font-style')"/>
<xsl:value-of select="substring-after(@style, 'italic;')"/>
</xsl:attribute>
<em>
<xsl:apply-templates select="node()"/>
</em>
</xsl:copy>
</xsl:template>
<xsl:template match="span[
contains(translate(@style, ' ', ''), 'font-weight:600')
]">
<xsl:copy>
<xsl:attribute name="style">
<xsl:value-of select="substring-before(@style, ' font-weight')"/>
<xsl:value-of select="substring-after(@style, '600;')"/>
</xsl:attribute>
<strong>
<xsl:apply-templates select="node()"/>
</strong>
</xsl:copy>
</xsl:template>
<xsl:template match="span[
contains(translate(@style, ' ', ''), 'text-decoration:underline')
]">
<xsl:copy>
<xsl:attribute name="style">
<xsl:value-of select="substring-before(@style, ' text-decoration')"/>
<xsl:value-of select="substring-after(@style, 'underline;')"/>
</xsl:attribute>
<u>
<xsl:apply-templates select="node()"/>
</u>
</xsl:copy>
</xsl:template>
这将生成不明确的规则警告,该警告在包含多个列出的属性的某些元素上无法正常工作。
输入的一个示例:
<span style=" text-decoration: underline; font-weight:600; color:#555555">some text</span>
转换为:
<span style=" font-weight:600; color:#555555"><u>some text</u></span>
当所需的结果是:
<span style="color:#555555"><b><u>some text</u></b></span>
我怎样才能修复这个不明确的规则匹配?
提前致谢
更新:
如果我将每个模板上的 priorty
设置为降序值,并在第一次 XSLT 运行的输出上再次运行 XSLT,则一切都会按预期工作。必须有一种比运行两次转换更简单的方法。有什么想法吗?
正如 Alejandro 和 Tomalak 所建议的,将 CSS 类的 style
属性替换为 class
属性也是一种选择。
This is a followup to this question.
I have several <span>
tags in a document with several semicolon separated style attributes. Right now I have 3 specific style attributes I'm looking for to translate into tags. All works well in the example above as long as the style attribute only contains one of the three style attributes. If a span has more, I get an ambiguous rule match.
The three style attributes I'm looking for are font-style:italic
, font-weight:600
, and text-decoration:underline
which should be removed from the style attribute and transformed into <em>
, <strong>
, and <u>
, respectively.
Here's my current XSLT:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="span[
contains(translate(@style, ' ', ''), 'font-style:italic')
]">
<xsl:copy>
<xsl:attribute name="style">
<xsl:value-of select="substring-before(@style, ' font-style')"/>
<xsl:value-of select="substring-after(@style, 'italic;')"/>
</xsl:attribute>
<em>
<xsl:apply-templates select="node()"/>
</em>
</xsl:copy>
</xsl:template>
<xsl:template match="span[
contains(translate(@style, ' ', ''), 'font-weight:600')
]">
<xsl:copy>
<xsl:attribute name="style">
<xsl:value-of select="substring-before(@style, ' font-weight')"/>
<xsl:value-of select="substring-after(@style, '600;')"/>
</xsl:attribute>
<strong>
<xsl:apply-templates select="node()"/>
</strong>
</xsl:copy>
</xsl:template>
<xsl:template match="span[
contains(translate(@style, ' ', ''), 'text-decoration:underline')
]">
<xsl:copy>
<xsl:attribute name="style">
<xsl:value-of select="substring-before(@style, ' text-decoration')"/>
<xsl:value-of select="substring-after(@style, 'underline;')"/>
</xsl:attribute>
<u>
<xsl:apply-templates select="node()"/>
</u>
</xsl:copy>
</xsl:template>
Which will generate the ambiguous rule warning doesn't work correctly on some elements that contain more than one of the listed attributes.
An example of the input:
<span style=" text-decoration: underline; font-weight:600; color:#555555">some text</span>
gets transformed to:
<span style=" font-weight:600; color:#555555"><u>some text</u></span>
when the desired result is:
<span style="color:#555555"><b><u>some text</u></b></span>
How can I fix the ambiguous rule match for this?
Thanks in advance
Update:
If i set priorty
on each of the templates to descending values and run the XSLT again on the output of the first XSLT run, everything works as expected. There has to be an easier way than running it through the transformation twice. Any ideas?
As Alejandro and Tomalak suggested, replacing the style
attributes with a class
attribute for CSS classes is an option, too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编辑:以防万一真正的问题被隐藏,我简化了样式表:
输出:
注意:使用空间标准化进行更简单的解析,以匹配存在比较中的属性。生成未经优化的内容(选择不匹配、选择匹配)。用于输出嵌套元素的“有状态”或“堆栈”命名模板。无论哪种方式,都有两个规则(identity和
span
,@style
覆盖它)和两个名称模板(解析器/标记器和嵌套内容的生成器)原始样式表:
注意:递归天堂。用于解析样式属性的嵌套标记器。嵌套内容的“有状态”模板(顺便说一句,还有性能匹配属性)
EDIT: Just in case real problem gets hide, I have simplified the stylesheet:
Output:
Note: Simpler parsing with space normalization to match properties in an existencial comparison. Generating content without optimization (selecting no match, selecting match). "Stateful" or "stackful" named template for output nested elements. Either way there are two rules (identity and
span
with@style
overwriting it) and two names templates (parser/tokenizer and generator of nested content)Original stylesheet:
Note: Recursion paradise. Nested tokenizer for parsing style properties. "Stateful" template for nested content (and performance matching properties, by the way)
这是一个使用 的
str-split-to-words
模板/函数的 XSLT 1.0 解决方案FXSL:当此转换应用于提供的 XML 文档时:
生成所需的正确结果:
Here is an XSLT 1.0 solution using the
str-split-to-words
template/function of FXSL:when this transformation is applied on the provided XML document:
the wanted, correct result is produced: