XSLT - 将<p>添加到文本字符串中,而不是\ n </p>

时间:2012-05-20 07:00:37

标签: html xml xslt replace find

我有一个这样的XML文档:

<xml>
  <item>
    <title>Article 1</title>
    <text><![CDATA[Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lorem diam, eleifend sed mollis id, condimentum in velit.

Sed sit amet erat ac mauris adipiscing elementum. Pellentesque eget quam augue, id faucibus magna.

Ut malesuada arcu eu elit sodales sodales. Morbi tristique porttitor tristique. Praesent eget vulputate dui. Cras ut tortor massa, at faucibus ligula.]]></text>
  </item>
</xml>

“段落”之间有空行。

我需要使用XSLT转换,其中元素的每段文本都在&lt; p>和&lt; / p&gt;。所以我想要的输出就像:

<h2>Article 1</h2>    
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lorem diam, eleifend sed mollis id, condimentum in velit.</p>
<p>Sed sit amet erat ac mauris adipiscing elementum. Pellentesque eget quam augue, id faucibus magna.</p>
<p>Ut malesuada arcu eu elit sodales sodales. Morbi tristique porttitor tristique. Praesent eget vulputate dui. Cras ut tortor massa, at faucibus ligula.</p>

到目前为止,我有一个看起来像这样的XSLT:

<xsl:template match="/">
        <html>
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
                <title>Page title</title>
            </head>
            <body>
                <h1>Table of contents</h1>
                <ol>
                <xsl:for-each select="xml/item>
                        <li><xsl:value-of select="./title"/></li>
                </xsl:for-each>
                </ol>
                <hr/>
                <xsl:for-each select="xml/item">
                    <h2><xsl:value-of select="./title"/></h2>
                    <xsl:value-of select="./text" disable-output-escaping="yes"/>
                </xsl:for-each>
            </body>
        </html>
</xsl:template>

如何使用段落HTML标记处理正确位置的\n替换?我在这里检查了类似的问题,但我显然无法将它们应用到我的问题中。

2 个答案:

答案 0 :(得分:3)

使用XSLT 2.0,您可以使用正则表达式来标记字符串。

为此,请将<xsl:value-of>替换为:

<xsl:analyze-string select="text" regex="&#xa;">
    <xsl:non-matching-substring>
        <p>
            <xsl:value-of select="."/>
        </p>
    </xsl:non-matching-substring>
</xsl:analyze-string>

在XSLT 1.0中,您必须定义一个将递归调用的模板,并在第一个换行符之前为子字符串生成<p>元素。

答案 1 :(得分:0)

如果必须使用XSLT 1.0,则以下命名模板可以完成此任务:

<xsl:template name="replace-nl">
  <xsl:param name="str"/>
  <xsl:if test="$str">
    <xsl:variable name="before" select="substring-before($str, '&#10;')"/>
    <xsl:variable name="after" select="substring-after($str, '&#10;')"/>      
    <p>
      <xsl:choose>
        <xsl:when test="$before">
          <xsl:value-of select="normalize-space($before)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="normalize-space($str)"/>
        </xsl:otherwise>
      </xsl:choose>
    </p>
    <xsl:call-template name="replace-nl">
      <xsl:with-param name="str" select="$after"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

只需将其替换为xsl:value-of,即可替换换行符,例如:

<xsl:for-each select="xml/item">
  ...
  <xsl:call-template name="replace-nl">
    <xsl:with-param name="str" select="text"/>
  </xsl:call-template>                    
</xsl:for-each>