使用XHTML和XML工具,有时我们需要反转斜体<i>
块。例如:
<!-- original text: -->
<p id="p1"><i>Several more</i> Homo sapiens <i>fossils were discovered</i>.</p>
<!-- same text, swapping italics: -->
<p id="p2">Several more <i>Homo sapiens</i> fossils were discovered.</p>
所以,看起来像这样,
发现了几个
发现了几个 Homo sapiens 化石。 有很多方法可以将“混合斜体”文本转换为“反斜体”:参见
What the correct algorithm to invert italics in a mixed text? ... ...但我看不出用“纯XSLT”做任何事情(没有外部处理依赖):你看到了吗?
答案 0 :(得分:1)
我不确定这是否会涵盖所有情况,但你可以这样做:
XML输入
<html>
<!-- original text: -->
<p id="p1"><i>Several more</i> Homo sapiens <i>fossils were discovered</i>.</p>
<!-- same text, swapping italics: -->
<p id="p2">Several more <i>Homo sapiens</i> fossils were discovered.</p>
<p>Leave me alone!</p>
<p><b><i>O</i>RIGINAL <big><i>with italics</i> and </big> withOUT</b></p>
</html>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[i]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()" mode="swapItal"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()" mode="swapItal" priority="1">
<i><xsl:value-of select="."/></i>
</xsl:template>
<xsl:template match="i" mode="swapItal">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()" mode="swapItal">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="swapItal"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML输出
<html>
<!-- original text: -->
<p id="p1">Several more<i> Homo sapiens </i>fossils were discovered<i>.</i></p>
<!-- same text, swapping italics: -->
<p id="p2"><i>Several more </i>Homo sapiens<i> fossils were discovered.</i></p>
<p>Leave me alone!</p>
<p><b>O<i>RIGINAL </i><big>with italics<i> and </i></big><i> withOUT</i></b></p>
</html>
输入已呈现
发现了几个 Homo sapiens 化石。
又发现了几个 Homo sapiens 化石。
别管我!
O RIGINAL with italics andOUT
输出呈现
发现了几个 Homo sapiens 化石。
发现了几个智人化石。
别管我!
O RIGINAL 用斜体和 withOUT
答案 1 :(得分:1)
这样的事情:
<xsl:template match="i" mode="invert-italic">
<xsl:apply-templates mode="invert-italic"/>
</xsl:template>
<xsl:template match="text()[not(ancestor::i)]" mode="invert-italic">
<i><xsl:copy-of select="."/></i>
</xsl:template>
<xsl:template match="node()" mode="invert-italic">
<xsl:copy>
<xsl:copy select="@*"/>
<xsl:apply-templates mode="invert-italic"/>
</xsl:copy>
</xsl:template>
答案 2 :(得分:0)
您好?别人会编辑? ......好吧,我需要“100%解决方案”,他们我只是为了finesh添加一个,但不是“我的”。
@MichaelKay和@DanielHaley展示了良好的线索,并且接近于精细的解决方案(!)。XML输入
<html>
<p><i>Several more</i> Homo sapiens <i>fossils were discovered</i>.</p>
<p>Several more <i>Homo sapiens</i> fossils were discovered.</p>
<p>Leave me alone!</p>
<p><b><i>F</i>RAGMENT <big><i>with italics</i> and </big> withOUT</b></p>
<p><i><sup><sub><sup><sub>Deep tags</sub></sup></sub></sup> here</i>
<big><b><small>and here</small></b></big>!
</p>
</html>
XSLT 1.0实施
@DanielHaley显示更好的结果(只有<p>Leave me alone!</p>
未反转),但@ MichaelKay的解决方案更优雅:我合并两者以产生这个“100%解决方案”。现在我在我的系统上使用这个XSLT作为“交换斜体算法”......直到现在都没有错误(!)。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:preserve-space elements="p"/>
<xsl:template match="@*|node()"> <!-- copy all -->
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="i"> <!-- remove tag i -->
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()[not(ancestor::i)]"> <!-- inlcude tag i -->
<i><xsl:copy-of select="."/></i>
</xsl:template>
</xsl:stylesheet>
在复制过程中概述为“按事件算法驱动”:
删除i
代码:将“<i>
thing </i>
”的任何内容复制为“ thing ”。
包含i
代码:将任何文字复制为“<i>
文字 </i>
”,当 text 不属于“斜体父母(或其他祖先)”的上下文。 PS: text 是DOM树的终端节点。