Xslt ';动态';规范化

Xslt ';动态';规范化,xslt,xslt-2.0,Xslt,Xslt 2.0,我不太确定该如何恰当地描述这个问题,但我面临的是以下问题。我在最初是html的文件中有相当多的空白内容。我想删除它,最简单的方法是使用一个标识模板并添加以下内容 <xsl:template match="text()"> <xsl:value-of select="normalize-space(.)"/> </xsl:template> 很好,但有点太好了。假设以下示例: <p> some content with w

我不太确定该如何恰当地描述这个问题,但我面临的是以下问题。我在最初是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>
有些内容带有空格和a,有些内容带有文本
如果我使用身份模板,当然会得到我的结果 看起来像

 <p>some content with whitespaces and a<a href="some_link">link</a>and some<strong>text</strong>
一些内容带有空格和A,还有一些文本
但是我想保留a和strong标记(或者基本上是“final”字符串中的任何标记)前面的空白。因为这些内容可以在相当多的标记(div、anchors等)中构建异常可能会起作用,但会变得相当复杂,因为我需要为可以位于另一个标记中的所有标记创建一个模板匹配循环,并在初始清理后再次添加空间

有更简单的方法吗

再次提前感谢!

也许吧

<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()">
  <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>

也许吧

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

以下是我的解决方案:

<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>
so zacharyyoung$xsltproc so.xsl so.xml
有些内容带有空格和a,有些内容带有文本

更新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>

标题文字
有些内容带有空格和a,有些内容带有文本

结果是:

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

标题文本
有些内容带有空格和a,有些内容带有文本

因此,这不是一般情况下的解决方案。

以下是我的解决方案:

<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>
so zacharyyoung$xsltproc so.xsl so.xml
有些内容带有空格和a,有些内容带有文本

更新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>

标题文字
有些内容带有空格和a,有些内容带有文本

结果是:

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

标题文本
有些内容带有空格和a,有些内容带有文本


所以这不是一个通用的案例解决方案。

我不明白
[self::*]
谓词实现了什么。请解释一下好吗?
前面的同级::节点()[1]
选择前面的第一个同级节点,它可以是元素、注释或处理指令节点。谓词
[self::*]
检查它是一个元素节点(而不是注释或处理指令)。@MartinHonnen:非常感谢,Martin。我已经更新了我的答案。我不明白
[self::*]
谓词实现了什么。请解释一下这一点好吗?
前面的同级::node()[1]
选择前面的第一个同级节点,它可以是元素、注释或处理指令节点。谓词
[self::*]
检查它是否是元素节点(不是评论或处理说明。@MartinHonnen:非常感谢,Martin。我已经更新了我的答案。谢谢Zach,效果很好!提供的其他解决方案也可能有效,但这一个对我来说更容易理解。@Wokoman:谢谢,尽管我很担心,因为Michael和Martin都比我更了解XSLT,而且他们都在使用额外的
[self::*]
谓词,我仍在努力理解它。请让我知道这个解决方案是否不是包罗万象的。这种方法不是在原始文本中没有空格的地方插入空格吗?例如,在
headingText
中,你会得到
标题文本
?以及注释和处理指令,作为同级也会导致正在添加空格。@MartinHonnen:是的,它确实有那些意想不到的影响。我将保留我的答案,因为它满足了OP的原始问题。@all Fair points,同时我注意到,当并非所有字符串都像上面的示例所示被“封装”时,上面的解决方案确实有一些副作用。因此,即使我喜欢过多的空白,它留下了一些不应该出现的地方。我会尝试一下其他选项,看看升级到这些选项是否有意义。(但不得不承认,当我看到它们时,我的大脑有点痛:-)谢谢Zach,工作起来很有魅力!提供的其他解决方案也可能有效,但这一个对我来说更容易理解。@Wokoman:谢谢,尽管我很担心,因为Michael和Martin都比我更了解XSLT,而且他们都在使用额外的
[self::*]
谓词,我仍在努力理解它。请让我知道这个解决方案是否不是包罗万象的。这种方法不是在原始文本中没有空格的地方插入空格吗?例如,在
headingText
中,你会得到
标题文本
?以及注释和处理指令,作为同级也会导致正在添加空格。@MartinHonnen:是的,它确实有那些意想不到的影响。我将保留我的答案,因为它满足了OP的原始问题。@all Fair points,同时我注意到,当并非所有字符串都像上面的示例所示被“封装”时,上面的解决方案确实有一些副作用。因此,即使我喜欢过多的空白,它留下了一些不应该出现的地方。我会尝试一下其他选项,看看升级到这些选项是否有意义。(但不得不承认,当我看到它们时,我的大脑有点痛:-)