我上周已经发布过有关邻近团体合并的问题。 我很新,可能还有一件事我不会......
所以我有一个模板,用它们的CSS类名合并相邻的组。
<xsl:template name="fusionElements">
<xsl:param name="classFusion" />
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:for-each-group select="node() except text()[not(normalize-space())]" group-adjacent="@class=$classFusion">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:for-each-group select="current-group()" group-by="concat(node-name(.), '|', $classFusion)">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="current-group()/node()" />
</xsl:element>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
然后我就像这样调用模板。我正在搜索具有相同CSS类的多个p
的{{1}}个节点。
span
<xsl:template match="p[contains(@class, 'Normal')][count(./span[contains(@class, 'USous-article')])>0]">
<xsl:call-template name="fusionElements">
<xsl:with-param name="classFusion" select="./span[1][contains(@class,'USous-article')]/@class" />
</xsl:call-template>
它正在工作,除非我在同一<xsl:template match="p[contains(@class, 'Normal')][count(./span[contains(@class, 'UCitation')])>0]">
<xsl:call-template name="fusionElements">
<xsl:with-param name="classFusion" select="./span[1][contains(@class,'UCitation')]/@class" />
</xsl:call-template>
p
我想做的是:
<p class="Normal">
<a name="Art10Prg1"><!--anchor--></a>
<span class="USous-article Default">§</span>
<span class="USous-article Default"> </span>
<span class="USous-article Default">1er</span>
<span class="USous-article Default"> </span>
<span class="USous-article Default">-</span>
<span class="UCitation Default">a)</span>
<span class="UCitation Default"> </span>
Some text!</p>
我理解错误(两个不同的模板匹配同一个节点),但我没有线索如何解决问题。
<p class="Normal">
<a name="Art10Prg1"><!--anchor--></a>
<span class="USous-article Default">§ 1er -</span>
<span class="UCitation Default">a) </span>
Some text!</p>
答案 0 :(得分:0)
我认为您可以将要检查的各种类定义为字符串序列,然后您可以使用一个分组构造(至少在我们有复合键的XSLT 3中):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">
<xsl:param name="classes-to-merge" as="xs:string*" select="'USous-article', 'UCitation'"/>
<xsl:output method="html" indent="yes" html-version="5.0"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="p[contains-token(@class, 'Normal') and span[some $class in $classes-to-merge satisfies contains-token(@class, $class)]]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="node() except text()[not(normalize-space())]" composite="yes" group-adjacent="node-name(), some $class in $classes-to-merge satisfies contains-token(@class, $class), @class">
<xsl:choose>
<xsl:when test="not(empty(current-grouping-key()[1])) and current-grouping-key()[2] and not(empty(current-grouping-key()[3]))">
<xsl:copy>
<xsl:apply-templates select="@*, current-group()/node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
改变
<p class="Normal">
<a name="Art10Prg1"><!--anchor--></a>
<span class="USous-article Default">§</span>
<span class="USous-article Default"> </span>
<span class="USous-article Default">1er</span>
<span class="USous-article Default"> </span>
<span class="USous-article Default">-</span>
<span class="foo">foo 1</span>
<span class="foo">foo 2</span>
<span class="UCitation Default">a)</span>
<span class="UCitation Default"> </span>
Some text!</p>
进入
<p class="Normal"><a name="Art10Prg1">
<!--anchor--></a><span class="USous-article Default">§ 1er -</span><span class="foo">foo 1</span><span class="foo">foo 2</span><span class="UCitation Default">a) </span>
Some text!
</p>
https://xsltfiddle.liberty-development.net/pPqsHSZ/1
使用XSLT 2,您可以尝试使用嵌套的for-each-group
,也可以连接分组关键组件以模拟复合键:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:function name="mf:contains-token" as="xs:boolean">
<xsl:param name="input" as="xs:string*"/>
<xsl:param name="token" as="xs:string"/>
<xsl:variable name="tokenized-input" as="xs:string*"
select="for $i in $input return tokenize($i, '\s+')"/>
<xsl:sequence
select="some $t in $tokenized-input satisfies $t = replace($token, '^\s+|\s+$', '')"/>
</xsl:function>
<xsl:param name="classes-to-merge" as="xs:string*" select="'USous-article', 'UCitation'"/>
<xsl:template match="p[mf:contains-token(@class, 'Normal') and span[some $class in $classes-to-merge satisfies mf:contains-token(@class, $class)]]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="node() except text()[not(normalize-space())]" group-adjacent="concat(node-name(.), '|', some $class in $classes-to-merge satisfies mf:contains-token(@class, $class), '|', @class)">
<xsl:variable name="grouping-keys" select="tokenize(current-grouping-key(), '\|')"/>
<xsl:choose>
<xsl:when test="$grouping-keys[1] and $grouping-keys[2] = 'true' and $grouping-keys[3]">
<xsl:copy>
<xsl:apply-templates select="@*, current-group()/node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:transform>