我有以下输入(xml的片段):
<prompt>
This is a sentence with <b>bold</b>.
<p>
This is in a paragraph element.
</p>
This is a <i>second</i> <b>sentence</b>.
</prompt>
我有一个匹配p
和prompt
的模板。在该模板中,它将内容包装在<PARAGRAPH>
个元素中。
对于上面的示例,所需的输出是:
<PARAGRAPH>
This is a sentence with bold.
</PARAGRAPH>
<PARAGRAPH>
This is in a paragraph element.
</PARAGRAPH>
<PARAGRAPH>
This is a second sentence.
</PARAGRAPH>
是否有某种方法可以根据元素名称将提示内容分解为组?特别是元素名称为非p和p?
的组我一直在阅读关于XSLT中的Muenchian分组策略,但看不到如何应用或者甚至可能这样做。也许我应该接近另一种方式?
答案 0 :(得分:4)
是否有某种方法可以将提示内容分解为群组 基于元素名称?
这并不是您向我们展示的内容 - 您的论坛基于<p>
元素作为文字节点之间的分隔符。
我一直在阅读有关XSLT中的Muenchian分组策略但是 无法看到如何申请或者甚至可以这样做。
这是可能的 - 但在这种情况下,它根本不是微不足道的。按照以下几点尝试:
XSLT 1.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="group-by-divider" match="prompt/node()[not(self::p)]" use="count(preceding-sibling::p)" />
<xsl:template match="/">
<root>
<xsl:apply-templates select="prompt"/>
</root>
</xsl:template>
<xsl:template match="prompt">
<xsl:apply-templates mode="group"/>
</xsl:template>
<xsl:template match="node()[not(self::p)][count(. | key('group-by-divider', count(preceding-sibling::p))[1]) = 1]" mode="group">
<PARAGRAPH>
<xsl:apply-templates select="key('group-by-divider', count(preceding-sibling::p))"/>
</PARAGRAPH>
</xsl:template>
<xsl:template match="p" mode="group">
<PARAGRAPHx>
<xsl:apply-templates/>
</PARAGRAPHx>
</xsl:template>
<!-- suppress nodes other than through the key -->
<xsl:template match="node()" mode="group"/>
</xsl:stylesheet>
您可能需要添加一些空白管理以使其更漂亮。
答案 1 :(得分:2)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="prompt">
<yourRoot>
<xsl:for-each-group select="node()" group-adjacent="name() = 'p'">
<PARAGRAPH>
<xsl:apply-templates select="current-group()"/>
</PARAGRAPH>
</xsl:for-each-group>
</yourRoot>
</xsl:template>
答案 2 :(得分:2)
以下样式表通过应用模板生成由<p>
元素分隔的字符串,然后使用递归模板将该字符串拆分为<paragraph>
元素。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:param name="delimiter" select="'|'"/>
<xsl:template match="prompt">
<xsl:call-template name="split-to-paragraph">
<xsl:with-param name="txt">
<xsl:apply-templates select="node()" />
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template match="prompt/node()">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="prompt/p" priority="1">
<xsl:value-of select="concat($delimiter, . ,$delimiter)"/>
</xsl:template>
<xsl:template name="split-to-paragraph">
<xsl:param name="delimiter" select="$delimiter"/>
<xsl:param name="txt"/>
<xsl:choose>
<xsl:when test="contains($txt, $delimiter)">
<PARAGRAPH>
<xsl:value-of select="normalize-space(
substring-before($txt, $delimiter))"/>
</PARAGRAPH>
<xsl:call-template name="split-to-paragraph">
<xsl:with-param name="delimiter" select="$delimiter"/>
<xsl:with-param name="txt"
select="substring-after($txt, $delimiter)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<PARAGRAPH>
<xsl:value-of select="normalize-space($txt)"/>
</PARAGRAPH>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>