2

我有一个这样的 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 转换,其中元素将在 < p > 和 </ p > 之间具有每一段文本。所以我想要的输出是这样的:

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

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

4

2 回答 2

3

With XSLT 2.0, you can use a regular expression to tokenize your string.

To do so, replace your <xsl:value-of> by:

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

In XSLT 1.0, you'd have to define a template that will be called recursively and generates a <p> element for the substring before the first linefeed.

于 2012-05-20T08:00:26.483 回答
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>
于 2012-05-20T08:28:34.913 回答