1

我目前有一个正在使用的 XML 提要,其中我有一个节点,其中包含一堆带有<p>标签的文本。然而,在每个标签之后似乎都有一个导致问题的空间。示例 XML 文档如下:

<Text>
<p> Sample Text.</p> <p> Sample Text..</p> <p> Sample Text.</p> <p> Sample Text.</p> <p> Sample Text.</p>
</Text>

我想通过删除每个<p>标签开头的空格将“文本”节点中的数据转换为如下所示。

<Text>
<p>Sample Text.</p> <p>Sample Text.</p> <p>Sample Text.</p> <p>Sample Text.</p> <p>Sample Text.</p>
</Text>

谁能帮我解决这个问题?

谢谢

4

5 回答 5

2

I. 去除任意数量连续空格的起始组的非递归 XSLT 1.0 解决方案

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

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

 <xsl:template match="p/text()">
  <xsl:value-of select=
   "substring-after
     (.,
      substring-before
        (.,
         substring
           (translate(., ' ', ''), 1, 1)
         )
      )"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<Text>
    <p> Sample Text.</p> <p> Sample Text..</p> <p> Sample Text.</p> <p> Sample Text.</p> <p> Sample Text.</p>
</Text>

产生了想要的正确结果:

<Text>
    <p>Sample Text.</p> <p>Sample Text..</p> <p>Sample Text.</p> <p>Sample Text.</p> <p>Sample Text.</p>
</Text>

说明

这个想法是:

  1. 获取第一个非空格字符。

  2. 获取该字符前面的空格字符串(在1.中获得)。

  3. 获取紧跟在该空格字符串之后的字符串(在 2. 中获得)。


二、XSLT 2.0 解决方案

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes"/>

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

 <xsl:template match="p/text()">
  <xsl:sequence select="replace(., '^\s+(.+)$', '$1')"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于同一个 XML 文档(如上)时,会产生相同的正确结果

<Text>
    <p>Sample Text.</p> <p>Sample Text..</p> <p>Sample Text.</p> <p>Sample Text.</p> <p>Sample Text.</p>
</Text>

请注意

Martin Honnen 建议使用:

replace(., '^\s+', '')

虽然这比:

replace(., '^\s+(.+)$', '$1')

后者效率更高,因为它只进行一次替换,而前者通常执行许多单独的替换。

更新:OP 无法使用 XSLT 2.0 解决方案,他在评论中写道:

我现在在想,看起来是一个空格的东西实际上可能是一个标签,我将如何检查它然后删除它?

解决方案就是使用:

replace(., '^[\s&#9;&#10;&#13;]+(.+)$', '$1')
于 2012-07-03T12:42:10.610 回答
1

使用身份转换模板

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

加上元素的第一个子p元素的模板

<xsl:template match="p/text()[1]">
  <xsl:value-of select="substring(., 2)"/>
</xsl:template>
于 2012-07-03T09:30:42.463 回答
0

这个模板:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <xsl:template match="Text/p/text()[1]">
    <xsl:call-template name="ltrim" />
  </xsl:template>

  <xsl:template name="ltrim">
    <xsl:param name="start" select="1" />

    <xsl:choose>
      <xsl:when test="substring(., $start, 1) = ' '">
        <xsl:call-template name="ltrim">
          <xsl:with-param name="start" select="$start + 1" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="substring(., $start)" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

<p>仅左修剪标签内容开头的任何空格。

它只留下所有其他空白。对于您的 XML,它返回:

<Text>
<p>Sample Text.</p> <p>Sample Text.</p> <p>Sample Text.</p> <p>Sample Text.</p> <p>Sample Text.</p>
</Text>
于 2012-07-03T09:34:03.477 回答
0

尝试以下 XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:template match="node()">
        <xsl:copy>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

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

</xsl:stylesheet>
于 2012-07-03T09:27:00.480 回答
-1

使用简单的搜索替换实用程序:http ://www.rjlsoftware.com/software/utility/search/

于 2012-07-03T09:19:47.400 回答