'动态'正常化

时间:2012-02-09 14:52:28

标签: xslt xslt-2.0

不太清楚我应该如何恰当地描述这个问题,但我面临的是以下几点。我在原来是html的文件中有一些空白内容。我想删除它,最简单的处理方法是使用身份模板并添加以下内容

    <xsl:template match="text()">
    <xsl:value-of select="normalize-space(.)"/>
</xsl:template>

工作正常,但有点太好了。假设以下示例:

<p>    some content with whitespaces and a <a href="some_link">link</a> and some <strong>text</strong>

如果我使用身份模板我的结果当然 看起来像

 <p>some content with whitespaces and a<a href="some_link">link</a>and some<strong>text</strong>

但是我想保留我的a和强标签前面的空格(或者基本上是'final'字符串中的任何标签。因为这些内容可以在相当多的标签(div,anchors等)中构建异常可能会工作,但会变得非常复杂,因为我需要为所有可以存在于另一个标签内的标签设置模板匹配循环,并在初始清理后再次添加空格。

任何更简单的方法来解决这个问题?

再次提前致谢!

3 个答案:

答案 0 :(得分:1)

这是我的解决方案:

<xsl:template match="text()">
  <xsl:if test="preceding-sibling::node()[1][self::*]">
    <xsl:text> </xsl:text>
  </xsl:if>
  <xsl:value-of select="normalize-space()"/>
  <xsl:if test="following-sibling::node()[1][self::*]">
    <xsl:text> </xsl:text>
  </xsl:if>
</xsl:template>

使用您的示例XML运行时产生:

so zacharyyoung$ xsltproc so.xsl so.xml
<?xml version="1.0"?>
<p>some content with whitespaces and a <a href="some_link">link</a> and some <strong>text</strong></p>

更新1

对于Martin的问题,这个解决方案确实引入了一些意想不到的效果。鉴于此输入:

<div>
  <h1>Heading</h1>Text
  <p>    some content with whitespaces and a <a href="some_link">link</a> and some <strong>text</strong></p>
</div>

结果是:

<?xml version="1.0"?>
<div>
  <h1>Heading</h1> Text
  <p>some content with whitespaces and a <a href="some_link">link</a> and some <strong>text</strong></p>
</div>

所以这是不是一般案例解决方案。

答案 1 :(得分:0)

也许

<xsl:template match="text()[not(preceding-sibling::node()[1][self::*]) and not(following-sibling::node()[1][self::*])]">
  <xsl:value-of select="normalize-space()"/>
</xsl:template>

<xsl:template match="text()[preceding-sibling::node()[1][self::*] and not(following-sibling::node()[1][self::*])">
  <xsl:value-of select="replace(., '\s+$', '')"/>
</xsl:template>

<xsl:template match="text()[not(preceding-sibling::node()[1][self::*]) and following-sibling::node()[1][self::*]">
  <xsl:value-of select="replace(., '^\s+', '')"/>
</xsl:template>

答案 2 :(得分:0)

也许

<xsl:template match="text()">
  <xsl:value-of select="concat(
    if (starts-with(., ' ') and preceding-sibling::node()[1][self::*]) then ' ' else '',
    normalize-space(.),
    if (ends-with(., ' ') and following-sibling::node()[1][self::*]) then ' ' else '')"/>
</xsl:template>