我使用以下XSLT 2.0对相邻的“内联”元素进行分组,但没有复制text()节点,有人知道为什么吗? 来源xml:
<para>
<p>some text</p>
<section>
<section>
<inline>inline text</inline>
<inline/>
<p>some more text</p>
<p/>
</section>
<para>
<p>dog</p>
<p/>
<p/>
<sub-para>
<p/>
<p/>
</sub-para>
</para>
</section>
</para>
我的XSLT 2.0样式表有2个模板匹配(用于text())和*(用于任何元素)
<xsl:template match="text()">
<xsl:copy />
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(self::inline)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<grp><xsl:copy-of select="current-group()"/></grp>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
我目前得到的结果是:
<para>
<p/>
<section>
<section>
<grp>
<inline>inline text</inline>
<inline/>
</grp>
<p/>
<p/>
</section>
<para>
<p/>
<p/>
<p/>
<sub-para>
<p/>
<p/>
</sub-para>
</para>
</section>
</para>
即。复制元素,对相邻的内联元素进行分组,但不复制任何文本节点。
为什么不调用apply-templates select = current-group()会导致调用text()模板?
非常感谢任何答案
答案 0 :(得分:0)
指令<xsl:for-each-group select="*"
选择子元素节点,而不选择子文本节点。因此,文本节点不会成为任何组的一部分,因此不会被复制。
您拥有与文本节点匹配的模板规则这一事实无关紧要,因为您从不将模板应用于文本节点。
如果更改for-each-group以选择文本节点(通过编写select="node()"
),则存在“内联”元素不再相邻的问题,因为它们由空白文本分隔节点
我不知道源词汇表,但我倾向于仅将分组模板用于“块级”元素(如para和section),并对具有文本或混合内容的元素使用标准身份模板
答案 1 :(得分:0)
正如迈克尔凯先生所说,你只是选择元素,而不是节点,所以你的文本节点永远不会被处理。
作为当前模板,你有匹配元素,然后处理子元素,我认为你需要的是第二个模板,它也匹配元素,但只有没有子元素的模板。在此模板中,您可以添加处理文本节点
<xsl:template match="*[not(*)]">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
由于此模板已指定条件,因此,当条件为真时,我应该优先考虑现有模板。
实际上,它甚至可以简化为
<xsl:template match="*[not(*)]">
<xsl:copy-of select="." />
</xsl:template>
值得指出的是,无论是否将模板应用于文本节点,实际上都不需要匹配 text()的当前模板。 XSLT具有内置模板的概念,当在XSLT中找不到节点的显式模板匹配时使用。这些内置模板无论如何都会输出文本节点,因此你所有的“text()”模板都是模板中的内置版本所做的。