XSL:在应用其后代模板时操作节点

时间:2017-11-17 14:04:47

标签: xml xslt

我使用XML文本版本,其中文本节点通常与元素节点一起出现。例如,<w>个单词元素包含文本节点,但也可能包含其他格式,例如信号缩写,包含在<choice>环境中:

<s><w>Any</w> <w>sentence</w> <w>may</w> <w>contain</w> <w>an</w> <w><choice>
 <abbr>abbr<am>.</am></abbr>
 <expan>abbr<ex>eviation</ex></expan></choice></w>.</s>

源稿件经常使用的字间距与我们通常放置空间的位置不同。此稿件字间距保留在<w>个字元素标签内,因此奇数间距的情况可能为<w>ele phant</w>。我的XSL样式表是使用一个参数来表示当前操作是否要输出稿件间距(&#34; ele phant&#34;)或词汇词间距(&#34; elephant&#34;)。

我的问题:如何有条件地从<w>个节点中删除间距,并确保所有后代模板仍然应用?

澄清一下,以下内容不起作用:

<xsl:strip-space>:此功能无法有条件地应用。我需要构建一个if子句来检查规范化参数是否处于活动状态,但strip-space仅允许在文档的顶层。

在以下环境中

<xsl:value-of>

<xsl:template match="w">
 <xsl:choose>
  <xsl:when test="contains($display, 'normalized')">
   <xsl:value-of select="translate(., ' ', '')"/>
  </xsl:when>
  <xsl:otherwise>
   <xsl:apply-templates/>
  </xsl:otherwise>
 </xsl:choose>
</xsl:template>

这里我的语法问题是为后代编写的模板被忽略,因此,例如,像上面第一个代码块中的<choice>环境输出缩写及其扩展而不是一个或者另一个。

最后,确保xsl:apply-templates示例中缺少递归的xsl:value-of不允许translate属性值中的select等语法。

如果满足<w>示例中的条件,但仍然应用任何后代节点的模板,如何从xsl:value-of节点的内容中删除所有间距?

使用XSLT 2.0。

1 个答案:

答案 0 :(得分:3)

我对用空白字符转录原始间距不太自信。如果你想记录奇数单词或字母间距,也许你应该考虑一个更明确的方法。例如,有<tei:space><w>ele phant</w>的奇数间距将被转录为<w>ele<space/>phant</w>。此外,您可以使用@quantity@unit来描述实际空间的宽度。使用XSL处理这样的元素比使用(空格)字符更容易和更可靠。

如果你想坚持我仍然认为合法的空白方法,Martin Honnen已经给出了一个有效而坚实的方法。要对此进行扩展,我会将其与@mode结合使用,而不是在每个节点上查询$display

<xsl:template match="w//text()" mode="normalizeSpace">
    <xsl:value-of select="translate(.,' ','')"/>
</xsl:template>

而是从主模板中调用它:

<xsl:choose>
    <xsl:when test="contains($display, 'normalized')">
        <xsl:apply-templates mode="normalizeSpace"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:apply-templates/>
    </xsl:otherwise>
</xsl:choose>

这将为您提供更大的灵活性来定义其他后期处理例程,并且可能也会提供更好的性能。