使用XSLT根据空标记更改周围数据

时间:2010-08-25 00:38:47

标签: html xml xslt

在尝试制作样式表以转换使用过时的SGML DTD进行格式化的书籍的旧LoC转录的过程中,我遇到了以下情况的障碍:

在转换后的XML文件中,有一些文本行如下所示:

<p> Text on left <hsep></hsep> Text on right </p>

hsep基本上将剩下的文本推向右对齐。不幸的是,我不知道有什么方法可以通过转换标签将其转换为HTML,因为HTML没有像hsep那样缺乏可疑的CSS黑客。我认为能够将其转换为以下内容会更有用:

<p> Text on left <span class="right">Text on right</span> </p>

但是,我不确定如何执行此操作,因为它需要在<p>元素中确定是否存在<hsep>,然后围绕剩余的文本创建标记在它存在的同时,还将模板应用于可能存在的任何元素。我不认为我有类似

的情况

<p> Text a <em> Text b <hsep></hsep> Text c </em> </p>

是常见的甚至存在,所以我认为这不会造成问题,但可能会出现以下情况:

<p> <em> Text a Text b <hsep></hsep> Text c </em> </p>

我可以想到涉及正则表达式的复杂,可怕的方法,但我希望这是一种非可怕的方式。

2 个答案:

答案 0 :(得分:2)

  

围绕剩下的标签创建一个标签   基于它的文本在那里,而   还将模板应用于任何模板   可能存在的元素

我认为为了更好的前瞻性处理,你可以使用这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="hsep">
        <span class="right">
            <xsl:apply-templates select="following-sibling::node()[1]"/>
        </span>
    </xsl:template>
</xsl:stylesheet>

使用Dimitre的输入:

<html>
  <p> Text a <em> Text b <hsep></hsep> Text c </em> </p>
  <p> <em> Text a Text b <hsep></hsep> Text c </em> </p>
</html>

输出:

<html>
<p> Text a <em> Text b <span class="right"> Text c </span></em></p>
<p><em> Text a Text b <span class="right"> Text c </span></em></p>
</html>

注意:对于out模式,您可以为hsep之前或之后的元素声明一次规则。

答案 1 :(得分:1)

此转化

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="hsep">
  <span class="right">
   <xsl:apply-templates mode="copy"
        select="following-sibling::node()"/>
  </span>
 </xsl:template>

 <xsl:template match="node()[preceding-sibling::hsep]"/>

 <xsl:template mode="copy"
  match="node()[preceding-sibling::hsep]">

  <xsl:call-template name="identity"/>
 </xsl:template>
</xsl:stylesheet>

应用于此文档时

<html>
  <p> Text a <em> Text b <hsep></hsep> Text c </em> </p>
  <p> <em> Text a Text b <hsep></hsep> Text c </em> </p>
</html>

生成想要的正确结果

<html>
   <p> Text a <em> Text b <span class="right"> Text c </span></em></p>
   <p><em> Text a Text b <span class="right"> Text c </span></em></p>
</html>