我有 XHTML 内容,其中存在具有相同 href 值的相邻锚标记,需要合并。我一直在尝试找出一种使用 XSL 模板来完成此操作的方法,但遇到了困难。
我已经根据“连接与 XSLT 共享属性值的标签的内容”中描述的解决方案设置了初始模板。这几乎得到了我需要的结果;然而,我的 XHTML 中相邻锚标记的内容通常包括文本节点中的子标记(例如,
<em></em>
、<code></code>
),并且必须保留这些子标记。它们被我当前的模板删除了。
我意识到在我当前的解决方案中,XPATH 表达式几乎肯定过于复杂,说实话,我不完全理解我的模板是如何产生这样的结果的。我完全愿意接受其他更简单或更明智的方法,这些方法将帮助我实现我正在寻找的结果。作为背景,我在带有 saxon-js 包的 Node.js 应用程序中使用模板,我认为除了 1.0 之外,它还支持 XSLT 2.0。
这是我的 XHTML 内容的代表性示例:
<section xmlns="http://www.w3.org/1999/xhtml">
<h1>Page heading</h1>
<p>I'm baby irony brunch <a href="http://www.url1.com">prism,</a><a href="http://www.url1.com"> </a><a href="http://www.url1.com"><em>farm-to-table</em> blog</a> vegan before they sold out. Viral cliche occupy neutral milk hotel prism drinking vinegar forage farm-to-table ennui tumblr.</p>
<p>Biodiesel jawn locavore irony <a href="http://www.url2.com">neutral milk</a><a href="http://www.url3.com"> hotel.</a> Ethical drinking vinegar gastropub pinterest taxidermy messenger bag next level. Plaid hot chicken enamel pin 8-bit vaporware scenester migas celiac direct trade twee fit DIY gorpcore tofu tousled.</p>
<p>Vape same small batch, fixie mukbang JOMO <a href="http://www.url4.com">gochujang</a> solarpunk single-origin <a href="http://www.url4.com">coffee</a> 3 wolf moon stumptown freegan. Truffaut selvage copper mug portland.</p>
<p>Viral yuccie drinking vinegar artisan. <a href="http://www.url5.com">Snackwave</a><a href="http://www.url5.com"> </a><a href="http://www.url5.com">taxidermy</a> cloud bread knausgaard artisan. Mustache YOLO unicorn poutine, leggings craft beer cold-pressed hexagon.</p>
</section>
这是我正在使用的模板:
<xsl:stylesheet xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="xhtml"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="*|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//xhtml:a[@href=following-sibling::xhtml:a/@href and following-sibling::node()[1][not(self::text())]]|//xhtml:a[@href=preceding-sibling::xhtml:a/@href and preceding-sibling::node()[1][not(self::text())]]">
<xsl:variable name="this-href" select="@href"/>
<xsl:if test="not(preceding-sibling::*[1][self::xhtml:a[@href = $this-href]])">
<xsl:copy>
<xsl:attribute name="href">
<xsl:value-of select="$this-href"/>
</xsl:attribute>
<xsl:apply-templates select="self::*" mode="concatenate" />
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="//xhtml:a[@href=following-sibling::xhtml:a/@href and following-sibling::node()[1][not(self::text())]]|//xhtml:a[@href=preceding-sibling::xhtml:a/@href and preceding-sibling::node()[1][not(self::text())]]" mode="concatenate">
<xsl:variable name="this-href" select="@href"/>
<xsl:value-of select="." />
<xsl:apply-templates select="following-sibling::*[1][self::xhtml:a[@href = $this-href]]|following-sibling::*[1][self::xhtml:a[@href = $this-href]]" mode="concatenate" />
</xsl:template>
</xsl:stylesheet>
这是输出:
<section xmlns="http://www.w3.org/1999/xhtml">
<h1>Page heading</h1>
<p>I'm baby irony brunch <a href="http://www.url1.com">prism, farm-to-table blog</a> vegan before they sold out. Viral cliche occupy neutral milk hotel prism drinking vinegar forage farm-to-table ennui tumblr.</p>
<p>Biodiesel jawn locavore irony <a href="http://www.url2.com">neutral milk</a><a href="http://www.url3.com"> hotel.</a> Ethical drinking vinegar gastropub pinterest taxidermy messenger bag next level. Plaid hot chicken enamel pin 8-bit vaporware scenester migas celiac direct trade twee fit DIY gorpcore tofu tousled.</p>
<p>Vape same small batch, fixie mukbang JOMO <a href="http://www.url4.com">gochujang</a> solarpunk single-origin <a href="http://www.url4.com">coffee</a> 3 wolf moon stumptown freegan. Truffaut selvage copper mug portland.</p>
<p>Viral yuccie drinking vinegar artisan. <a href="http://www.url5.com">Snackwave taxidermy</a> cloud bread knausgaard artisan. Mustache YOLO unicorn poutine, leggings craft beer cold-pressed hexagon.</p>
</section>
这是一个小提琴显示上述内容。
这与我需要的结果非常接近,只是我必须保留可能出现在具有匹配 href 值的相邻锚标记中的任何子标记,例如
<em></em>
或 <strong></strong>
。感谢您为 XSLT 新手提供的任何帮助!
我怀疑这就像改变一样简单
<xsl:value-of select="." />
到
<xsl:copy-of select="child::node()"/>
在
mode="concatenate"
模板规则中。
我不禁感觉你的后续兄弟测试条件比他们需要的要复杂得多,但也许那是因为我没有正确理解你的要求。