对于纯XSLT,“交换斜体算法”,你知道吗?

时间:2013-06-17 20:11:11

标签: algorithm xslt xhtml

使用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. 发现了几个 Homo sapiens 化石。


  3. 有很多方法可以将“混合斜体”文本转换为“反斜体”:参见 What the correct algorithm to invert italics in a mixed text? ...

    ...但我看不出用“纯XSLT”做任何事情(没有外部处理依赖):你看到了吗?

3 个答案:

答案 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树的终端节点。