我可以使用 XSLT 1.0 在 XML 元素的文本内容周围添加 <p></p> 标签吗?

Can I add <p></p> tags around text content in XML elements using XSLT 1.0?

我目前正在整理一个动态 HTML 模板,该模板由 XML 数据和 XSLT (1.0) 的简单文档组合提供便利,但我'我最近遇到了一个问题,希望得到一些建议。

在我的 XML 和 XSLT 文档之间建立连接后,我一直在使用标准 <xsl:value-of select="xxxxxx/xxxxxx"/> 命令来绘制我的 XML 元素中的文本节点并输出这些在 HTML 模板上。太棒了!

但是,我在这个过程中遇到了问题。

我的一个 XML 元素(在此示例中 <synopsis></synopsis>)包含大量文本,目前由换行符分隔,理想情况下我需要将其呈现为(三个单独的)段落我的 HTML 页面。

让我与您分享XML数据示例:

<bookstore>
  <book>
    <title>Harry Potter and the Philosopher's Stone</title>
    <author>J K. Rowling</author>
    <year>1997</year>
    <price>3.99</price>
    <publisher>Bloomsbury (UK)</publisher>
    <synopsis>
         Harry Potter and the Philosopher's Stone is the first novel in the Harry Potter series and J. K. Rowling's debut novel. 

         The plot follows Harry Potter, a young wizard who discovers his magical heritage as he makes close friends and a few enemies in his first year at the Hogwarts School of Witchcraft and Wizardry. 

         With the help of his friends, Harry faces an attempted comeback by the dark wizard Lord Voldemort, who killed Harry's parents, but failed to kill Harry when he was just a year old.
   </synopsis>
 </book>
 <book>
    <title>The Girl with the Dragon Tattoo</title>
    <author>Stieg Larsson</author>
    <year>2005</year>
    <price>5.99</price>
    <publisher>Norstedts Förlag (SWE)</publisher>
    <synopsis>
         In Stockholm, Sweden, journalist Mikael Blomkvist, co-owner of Millennium magazine, has lost a libel case brought against him by businessman Hans-Erik Wennerström. Lisbeth Salander, a brilliant but troubled investigator and hacker, compiles an extensive background check on Blomkvist for business magnate Henrik Vanger, who has a special task for him. 

         In exchange for the promise of damning information about Wennerström, Blomkvist agrees to investigate the disappearance and assumed murder of Henrik's grandniece, Harriet, 40 years ago. 

         After moving to the Vanger family's compound, Blomkvist uncovers a notebook containing a list of names and numbers that no one has been able to decipher.
    </synopsis>
  </book>
</bookstore>

当使用 <xsl:value-of select="xxxxxx/xxxxxx"/> 命令时,我当前的 <synopsis></synopsis> 元素输出显然是一个没有空格的连续文本块(在三个段落之间); 哈利波特 示例:

    Harry Potter and the Philosopher's Stone is the first novel in the Harry Potter series and J. K. Rowling's debut novel.The plot follows Harry Potter, a young wizard who discovers his magical heritage as he makes close friends and a few enemies in his first year at the Hogwarts School of Witchcraft and Wizardry.With the help of his friends, Harry faces an attempted comeback by the dark wizard Lord Voldemort, who killed Harry's parents, but failed to kill Harry when he was just a year old.

我想在我的 HTML 输出中实现的(希望 XLST 1.0 中的模板能够提供便利)是:

    <p>Harry Potter and the Philosopher's Stone is the first novel in the Harry Potter series and J. K. Rowling's debut novel.</p>

    <p>The plot follows Harry Potter, a young wizard who discovers his magical heritage as he makes close friends and a few enemies in his first year at the Hogwarts School of Witchcraft and Wizardry.</p>

    <p>With the help of his friends, Harry faces an attempted comeback by the dark wizard Lord Voldemort, who killed Harry's parents, but failed to kill Harry when he was just a year old.</p>

所以这是我的主要问题。可以通过我的 XSLT (1.0) 文件中的某种形式的模板来实现(上述)解决方案吗?这甚至可以做到吗?

我可以设置一个字符串变量(<synopsis>)然后搜索它并在文本段落中找到每个完整的 stop/line 中断并在这些点换行 <p></p> 标签围绕这部分字符串选择形成我的段落?

如果这确实是一个前景,我想在未来的基础上进一步发展,并可能添加一些进一步的 HTML 标签,例如 <ol><li><li></ol>

任何关于这是否可以实现的帮助或建议都会受到热烈欢迎。

正如 michael.hor257k 在他的有用评论(上面)中所揭示的那样,这个问题的解决方案围绕着 标记化 ,这是我在使用之前没有遇到过的XSLT.

在此 post(接受的答案)中使用 michael.hor257k 方便的基于定界符的解决方案 - - 我能够将元素的文本输出到单独的段落中。

已更新 XML:(请注意我要转换为段落的文本各部分周围的星号)

    <synopsis>
         *Harry Potter and the Philosopher's Stone is the first novel in the Harry Potter series and J. K. Rowling's debut novel.* 

         *The plot follows Harry Potter, a young wizard who discovers his magical heritage as he makes close friends and a few enemies in his first year at the Hogwarts School of Witchcraft and Wizardry.* 

         *With the help of his friends, Harry faces an attempted comeback by the dark wizard Lord Voldemort, who killed Harry's parents, but failed to kill Harry when he was just a year old.*
   </synopsis>

XSLT 模板:

<xsl:template name="paragraphs">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="'*'"/>
<xsl:choose>
    <xsl:when test="contains($text, $delimiter) and contains(substring-after($text, $delimiter), $delimiter)">
        <xsl:value-of select="substring-before($text, $delimiter)"/>
        <p>
            <xsl:value-of select="substring-before(substring-after($text, $delimiter), $delimiter)"/>
        </p>
        <!-- recursive call -->
        <xsl:call-template name="paragraphs">
            <xsl:with-param name="text" select="substring-after(substring-after($text, $delimiter), $delimiter)"/>
        </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$text"/>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

调用 XSLT 模板:

<xsl:for-each select="/dataroot/bookstore/book">
    <xsl:call-template name="paragraphs">
         <xsl:with-param name="text" select="synopsis"/>
    </xsl:call-template>
</xsl:for-each>

HTML 输出:

    <p>Harry Potter and the Philosopher's Stone is the first novel in the Harry Potter series and J. K. Rowling's debut novel.</p>

    <p>The plot follows Harry Potter, a young wizard who discovers his magical heritage as he makes close friends and a few enemies in his first year at the Hogwarts School of Witchcraft and Wizardry.</p>

    <p>With the help of his friends, Harry faces an attempted comeback by the dark wizard Lord Voldemort, who killed Harry's parents, but failed to kill Harry when he was just a year old.</p>

...还有一位满意的顾客!!

我还做了这个简化的 XML 转换以显示段落输出的动作 - http://xsltransform.net/6r5Gh2B

我认为没有必要修改您原来的 XML 输入。您可以简单地使用换行符作为分隔符(并对剩余的空格应用一些规范化):

<xsl:template match="synopsis">
    Synopsis: <span style="color:#38A930">
    <xsl:call-template name="tokenize">
        <xsl:with-param name="text" select="."/>
    </xsl:call-template>
    </span>
    <br/>
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="'&#10;'"/>
        <xsl:variable name="token" select="normalize-space(substring-before(concat($text, $delimiter), $delimiter))" />
        <xsl:if test="$token">
            <p>
                <xsl:value-of select="$token"/>
            </p>
        </xsl:if>
        <xsl:if test="contains($text, $delimiter)">
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
            </xsl:call-template>
        </xsl:if>
</xsl:template>