所以这篇文章的标题可能有点误导,但这是我能想到的最好的。我正在开发一个使用TEI编码文本的项目。我当前工作的一个要求是编写XSL转换以将XML编码的文本呈现为HTML。在大多数情况下,没问题。不过,我有点困在这个问题上:
<l>There is <delSpan spanTo="A1"/>deleted text spanning</l>
<l>multiple lines here.<anchor xml:id="A1"/> More text...</l>
或者,在其他情况下:
<delSpan spanTo="A2"/>
<l>Several deleted lines -- the delspan marker can appear </l>
<l>outside of an l element.... </l>
<anchor xml:id="A2"/>
(如果您不熟悉TEI:l =一行文字; delSpan =已删除文本的范围,包括多于一行,一页或更小的单位。)
目标是在delSpan(A1)及其对应的锚点(A1)之间显示文本 - “删除文本跨越/此处有多行” - 带有一些表示删除的格式(例如,text-decoration = “线通”)。现在,有一个“l”元素的模板可以处理大多数文本格式 - 或者至少调用其他模板来完成它。
但这些单身标签是异常的;所有其他格式化/标记都是使用实际包含要格式化的文本的标记来完成的。我是否正确地假设我需要在“l”模板中处理delSpan和锚元素?处理此问题并处理伪重叠元素的最优雅方法是什么?
很抱歉,如果这是一个noob问题,或者我没有提供足够的信息。我主要是一个很少有XSLT经验的C / C ++程序员,所以我很感激任何建议。
答案 0 :(得分:2)
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="delSpan|anchor"/>
<xsl:template match="text()[preceding::delSpan[1]/@spanTo=following::anchor[1]/@xml:id]">
<span style="text-decoration:line-through;">
<xsl:value-of select="."/>
</span>
</xsl:template>
</xsl:stylesheet>
输出:
<doc>
<l>There is <span style="text-decoration:line-through;">deleted text spanning</span></l>
<l><span style="text-decoration:line-through;">multiple lines here.</span> More text...</l>
</doc>
注意:使用前后轴及其在文档顺序中的含义。我们不会覆盖匹配l
元素的任何previus模板。 <{1}}和delSpan
也可能没有条纹。
答案 1 :(得分:1)
这里的主要问题是delSpan
元素不是父元素,它的结束和结束“元素”是一个空元素(anchor
用于关闭)。打开和关闭之间的链接是通过引用xml:id
标记来完成的。
这个问题有多个解决方案,这里有一个从头到尾,假设您使用XSLT 1.0(使用XSLT 2.0更容易)。这个想法很简单:找到所有兄弟姐妹并应用它们,但前提是它们本身后面跟着一个兄弟anchor
并使用正确的xml:id
:
<xsl:template match="delSpan">
<xsl:variable select="@spanTo" name="spanTo" />
<xsl:apply-templates select="following-sibling::*[following-sibling::anchor[@xml:id = $spanTo]" mode="deleted" />
</xsl:template>
<!--
do this for all elements you need to treat inside delSpan
if they have children, remember to use apply-templates with mode deleted
-->
<xsl:template match="l" mode="deleted">
<strike><xsl:value-of select="." /></strike>
</xsl:template>
我不是100%确定这是完全正确的。如果<delSpan>
可以嵌套,则可能会出错。如果你很幸运,Dimitri Novatchev也会走过去看看。