使用 XSLT 合并/连接共享属性值的相邻标签,而不会丢失子标签

问题描述 投票:0回答:1

我有 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 新手提供的任何帮助!

xslt xslt-1.0 xslt-2.0 xslt-grouping saxon-js
1个回答
0
投票

我怀疑这就像改变一样简单

<xsl:value-of select="." />

<xsl:copy-of select="child::node()"/>

mode="concatenate"
模板规则中。

我不禁感觉你的后续兄弟测试条件比他们需要的要复杂得多,但也许那是因为我没有正确理解你的要求。

© www.soinside.com 2019 - 2024. All rights reserved.