gpt4 book ai didi

xml - 合并 XSLT 中的元素序列

转载 作者:数据小太阳 更新时间:2023-10-29 02:27:58 26 4
gpt4 key购买 nike

我有一大堆自动生成的 HTML 在做这样愚蠢的事情:

 <p>Hey it's <em>italic</em><em>italic</em>!</p>

我想把它归结为:

 <p>Hey it's <em>italicitalic</em>!</p>

我的第一次尝试是沿着这些思路......

<xsl:template match="em/preceding::em">
<xsl:value-of select="$OPEN_EM"/>
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="em/following::em">
<xsl:apply-templates/>
<xsl:value-of select="$CLOSE_EM"/>
</xsl:template>

但显然 XSLT 规范以其祖母般的善意禁止使用标准 XPath precedingfollowing模板匹配器中的轴。 (无论如何,这都需要一些调整才能连续处理三个 em。)

有什么比忘记在 XSLT 中执行此操作并只运行 replace('</em><em>', '') 更好的解决方案了?在 $LANGUAGE_OF_CHOICE 上的最终结果?粗略的要求:不应合并两个 <em>如果它们被任何东西(空格、文本、标签)分隔,虽然它不必合并它们,但如果有三个或更多 <em>,它至少应该生成有效的 XML连续。不需要处理嵌套在 em(包括其他 em)中的标签。

(哦,我见过 how to merge element using xslt? ,它很相似但不完全相同。遗憾的是,XSLT 2 不是一个选项,而且建议的解决方案看起来非常复杂。)

最佳答案

这也类似于对相邻元素进行分组:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="em">
<em>
<xsl:call-template name="merge"/>
</em>
<xsl:apply-templates
select="following-sibling::node()[not(self::em)][1]"/>
</xsl:template>
<xsl:template match="node()" mode="merge"/>
<xsl:template match="em" name="merge" mode="merge" >
<xsl:apply-templates select="node()[1]"/>
<xsl:apply-templates select="following-sibling::node()[1]"
mode="merge"/>
</xsl:template>
</xsl:stylesheet>

输出:

<p>Hey it's <em>italicitalic</em>!</p>

注意:细粒度遍历恒等式规则(复制所有内容,逐个节点); em 规则(总是第一个,因为这个过程是逐个节点的),包装并调用 merge 模板,将模板应用到下一个兄弟而不是 em ; em 规则在 merge 模式(也称为 merge),适用于第一个 child 的模板(这种情况下它只是一个文本节点,但这允许嵌套元素),然后在 merge 模式下到下一个兄弟节点; “打破”规则,匹配任何不是 em 的东西(因为名称测试优先于节点类型测试)停止进程。

关于xml - 合并 XSLT 中的元素序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4048967/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com