分组元素不能正常工作
Grouping the element not working properly
我想根据其属性值对 r
元素进行分组:
- 如果当前和后续
r
个元素的属性值相同
那么所有的东西都应该包裹在一个 r
元素中。
- 需要删除前面有
r
的所有 r
元素
相同的属性和
值。
- 如果存在相同元素的空序列则只保留
一.
我面临的问题是:- 它删除了最后一个 r
您可以参考突出显示。 3 与上面的合并
XML:
<text width="12240" height="15840" orient="">
<p style="pxpub">
<r/>
<r/>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"/>
<r/>
<r pub="first">1 </r>
<r pub="first">2some text</r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"/>
<r pub="first"/>
<r/>
<r pub="a">1 some text</r>
<r pub="a"> 2 merge with above one</r>
<r pub="a"> 3 merge with above one</r>
<r pub="first"/>
<r pub="b"> 4 merge with above one</r>
<r pub="b"> 5 merge with above one</r>
<r pub="second"/>
</p>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output method="xhtml"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="r">
<xsl:variable name="selfattval" select="string-join(.//@*,'')"/>
<xsl:choose>
<xsl:when test="preceding-sibling::*[1][self::r[string-join(distinct-values(.//@*),'') = $selfattval]]/node()"/>
<xsl:when test="$selfattval = preceding-sibling::*[1][self::r]/string-join(distinct-values(.//@*),'')"/>
<xsl:otherwise>
<r>
<xsl:apply-templates select="@* | node()"/>
<xsl:apply-templates select="following-sibling::*[1][self::r[string-join(distinct-values(.//@*),'') = $selfattval]]/node()"/>
</r>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
当前输出:
<text width="12240" height="15840" orient="">
<p style="pxpub">
<r></r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"></r>
<r></r>
<r pub="first">1 2some text</r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"></r>
<r></r>
<r pub="a">1 some text 2 merge with above one</r>
<r pub="first"></r>
<r pub="b"> 4 merge with above one 5 merge with above one</r>
<r pub="second"></r>
</p>
</text>
期望输出:
<text width="12240" height="15840" orient="">
<p style="pxpub">
<r></r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"></r>
<r></r>
<r pub="first">1 2some text</r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"></r>
<r></r>
<r pub="a">1 some text 2 merge with above one 3 merge with above one</r>
<r pub="first"></r>
<r pub="b"> 4 merge with above one 5 merge with above one</r>
<r pub="second"></r>
</p>
这听起来像是 for-each-group group-adjacent
的任务:
<xsl:template match="*[r]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="r" group-adjacent="@*" composite="yes">
<xsl:copy>
<xsl:apply-templates select="@*, current-group()/node()"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
这是自 Saxon 9.8 和 Saxon JS 2 以来支持的 XSLT 3,但只要您只有 pub
属性使用
<xsl:template match="*[r]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="r" group-adjacent="@*">
<xsl:copy>
<xsl:apply-templates select="@*, current-group()/node()"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
应该在 XSLT 2 中做同样的事情,或者如果您有多个属性并且需要它们全部用于分组键,string-join
例如group-adjacent="string-join(@*, '|')"
它们在 XSLT 2 中。
我想根据其属性值对 r
元素进行分组:
- 如果当前和后续
r
个元素的属性值相同 那么所有的东西都应该包裹在一个r
元素中。 - 需要删除前面有
r
的所有r
元素 相同的属性和 值。 - 如果存在相同元素的空序列则只保留 一.
我面临的问题是:- 它删除了最后一个 r
您可以参考突出显示。 3 与上面的合并
XML:
<text width="12240" height="15840" orient="">
<p style="pxpub">
<r/>
<r/>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"/>
<r/>
<r pub="first">1 </r>
<r pub="first">2some text</r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"/>
<r pub="first"/>
<r/>
<r pub="a">1 some text</r>
<r pub="a"> 2 merge with above one</r>
<r pub="a"> 3 merge with above one</r>
<r pub="first"/>
<r pub="b"> 4 merge with above one</r>
<r pub="b"> 5 merge with above one</r>
<r pub="second"/>
</p>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output method="xhtml"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="r">
<xsl:variable name="selfattval" select="string-join(.//@*,'')"/>
<xsl:choose>
<xsl:when test="preceding-sibling::*[1][self::r[string-join(distinct-values(.//@*),'') = $selfattval]]/node()"/>
<xsl:when test="$selfattval = preceding-sibling::*[1][self::r]/string-join(distinct-values(.//@*),'')"/>
<xsl:otherwise>
<r>
<xsl:apply-templates select="@* | node()"/>
<xsl:apply-templates select="following-sibling::*[1][self::r[string-join(distinct-values(.//@*),'') = $selfattval]]/node()"/>
</r>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
当前输出:
<text width="12240" height="15840" orient="">
<p style="pxpub">
<r></r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"></r>
<r></r>
<r pub="first">1 2some text</r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"></r>
<r></r>
<r pub="a">1 some text 2 merge with above one</r>
<r pub="first"></r>
<r pub="b"> 4 merge with above one 5 merge with above one</r>
<r pub="second"></r>
</p>
</text>
期望输出:
<text width="12240" height="15840" orient="">
<p style="pxpub">
<r></r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"></r>
<r></r>
<r pub="first">1 2some text</r>
</p>
<p type="itemlist" style="TRH2">
<r pub="first"></r>
<r></r>
<r pub="a">1 some text 2 merge with above one 3 merge with above one</r>
<r pub="first"></r>
<r pub="b"> 4 merge with above one 5 merge with above one</r>
<r pub="second"></r>
</p>
这听起来像是 for-each-group group-adjacent
的任务:
<xsl:template match="*[r]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="r" group-adjacent="@*" composite="yes">
<xsl:copy>
<xsl:apply-templates select="@*, current-group()/node()"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
这是自 Saxon 9.8 和 Saxon JS 2 以来支持的 XSLT 3,但只要您只有 pub
属性使用
<xsl:template match="*[r]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="r" group-adjacent="@*">
<xsl:copy>
<xsl:apply-templates select="@*, current-group()/node()"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
应该在 XSLT 2 中做同样的事情,或者如果您有多个属性并且需要它们全部用于分组键,string-join
例如group-adjacent="string-join(@*, '|')"
它们在 XSLT 2 中。