0

使用 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>

所以,看起来像这样,

  1. 又发现了几块智人化石

  2. 又发现了几块智人化石。


有很多方法可以将“混合斜体”文本转换为“反转斜体”:请参阅 在混合文本中反转斜体的正确算法是什么?...

...但是我看不到任何使用“纯 XSLT”(没有外部处理依赖)的方法:你看到了吗?

4

3 回答 3

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>

输入渲染

又发现了几块智人化石

又发现了几块智人化石。

请别打扰我!

O RIGINAL带斜体和不带


输出渲染

又发现了几块智人化石

又发现了几块智人化石。

请别打扰我!

O RIGINAL带斜体不带

于 2013-06-17T20:41:08.227 回答
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>
于 2013-06-17T20:52:30.410 回答
0

你好?别人会编辑吗?...好吧,我需要“100% 解决方案”,我正在添加一个,仅用于精细,但不是“我的”。

@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>

在复制过程中概述为“事件驱动算法”:

  • 删除标签:将“ thingi ”的任何东西复制为“ <i> thing ”。</i>

  • 包含i标签:当文本不在“斜体父母(或另一个祖先)”的上下文中时,将任何文本复制为“<i> 文本”。 PS:text是DOM树的一个终端节点。</i>

于 2013-06-19T01:24:46.543 回答