admin管理员组文章数量:1415683
I apologize in advance if this has already been asked and answered in another post.
I've been banging my head for a bit on this problem and haven't yet found a complete solution.
Here's my problem:
I have several cases where a parent element contains multiple sets of direct sibling elements. Each set needs to be merged into a single element along with any of their children elements. And each set is interspersed with text. For example:
XML Input
<p>Information about specific mio levels, accessed as
<codeph><i>metaMio</i></codeph><codeph>[</codeph><codeph><i>N</i></codeph><codeph>]</codeph>
, in which
<codeph><i>N</i></codeph><codeph> < kMaxMioLevels</codeph>
.
</p>
Desired XML Output
<p>Information about specific mio levels, accessed as
<codeph><i>metaMio</i>[<i>N</i>]</codeph>
, in which
<codeph><i>N</i> < kMaxMioLevels</codeph>
.
</p>
Here's what I've tried so far, but I've found it duplicates the contents of the second element in the second set:
Attempted XSLT
<xsl:template match="codeph[not(preceding-sibling::node()[1][./local-name()='codeph'])][following-sibling::node()[1][./local-name()='codeph']]">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates/>
<xsl:choose>
<xsl:when test="following-sibling::codeph[preceding-sibling::node()[position()=1][local-name()='codeph']]">
<xsl:apply-templates select="following-sibling::codeph[preceding-sibling::node()[position()=1][local-name()='codeph']]" mode="codeph-merger"/>
</xsl:when>
<xsl:when test="following-sibling::*[1][text()[not(parent::codeph)]]"/>
</xsl:choose>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="codeph-merger">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="codeph[preceding-sibling::node()[1][local-name()='codeph']]"/>
Current Output
The above XSLT creates the following output, which is close but duplicates text (< kMaxMipLevels
):
<p>Information about specific mio levels, accessed as
<codeph><i>metaMio</i>[<i>N</i>] < kMaxMipLevels</codeph>
, in which
<codeph><i>N</i> < kMaxMipLevels</codeph>
.
</p>
I've also attempted to use the group-adjacent as part of the xsl:for-each-group but couldn't find any way for it to work on this case.
I'm using XSLT 2.0 and Saxon-HE 12.4 as part of the DITA-OT 4.2.4.
Thanks for any help you can provide.
I apologize in advance if this has already been asked and answered in another post.
I've been banging my head for a bit on this problem and haven't yet found a complete solution.
Here's my problem:
I have several cases where a parent element contains multiple sets of direct sibling elements. Each set needs to be merged into a single element along with any of their children elements. And each set is interspersed with text. For example:
XML Input
<p>Information about specific mio levels, accessed as
<codeph><i>metaMio</i></codeph><codeph>[</codeph><codeph><i>N</i></codeph><codeph>]</codeph>
, in which
<codeph><i>N</i></codeph><codeph> < kMaxMioLevels</codeph>
.
</p>
Desired XML Output
<p>Information about specific mio levels, accessed as
<codeph><i>metaMio</i>[<i>N</i>]</codeph>
, in which
<codeph><i>N</i> < kMaxMioLevels</codeph>
.
</p>
Here's what I've tried so far, but I've found it duplicates the contents of the second element in the second set:
Attempted XSLT
<xsl:template match="codeph[not(preceding-sibling::node()[1][./local-name()='codeph'])][following-sibling::node()[1][./local-name()='codeph']]">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates/>
<xsl:choose>
<xsl:when test="following-sibling::codeph[preceding-sibling::node()[position()=1][local-name()='codeph']]">
<xsl:apply-templates select="following-sibling::codeph[preceding-sibling::node()[position()=1][local-name()='codeph']]" mode="codeph-merger"/>
</xsl:when>
<xsl:when test="following-sibling::*[1][text()[not(parent::codeph)]]"/>
</xsl:choose>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="codeph-merger">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="codeph[preceding-sibling::node()[1][local-name()='codeph']]"/>
Current Output
The above XSLT creates the following output, which is close but duplicates text (< kMaxMipLevels
):
<p>Information about specific mio levels, accessed as
<codeph><i>metaMio</i>[<i>N</i>] < kMaxMipLevels</codeph>
, in which
<codeph><i>N</i> < kMaxMipLevels</codeph>
.
</p>
I've also attempted to use the group-adjacent as part of the xsl:for-each-group but couldn't find any way for it to work on this case.
I'm using XSLT 2.0 and Saxon-HE 12.4 as part of the DITA-OT 4.2.4.
Thanks for any help you can provide.
Share Improve this question asked Feb 4 at 18:27 DanielDaniel 232 bronze badges1 Answer
Reset to default 1A better explanation of the required logic would be useful. As it is, the following code seems to produce the wanted result in the given example:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3./1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p[codeph]">
<xsl:copy>
<xsl:for-each-group select="codeph|text()" group-adjacent="boolean(self::codeph)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<codeph>
<xsl:apply-templates select="current-group()/node()"/>
</codeph>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
本文标签: xsltMerge Direct Sibling Elements Interspersed with TextStack Overflow
版权声明:本文标题:xslt - Merge Direct Sibling Elements Interspersed with Text - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745239544a2649240.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论