简体   繁体   English

XSLT 2.0-如何合并同级元素

[英]XSLT 2.0 - how to merge sibling elements

How can I merge a specific element with adjacent siblings of the same type into a single element? 如何将特定元素与相同类型的相邻兄弟合并到单个元素中? I feel this should be simple but can't find an answer. 我觉得这应该很简单,但是找不到答案。

My code: 我的代码:

...
<nodeX>
  <a>words</a>
  <b>things</b>
  <g>hi</g>
  <g>there</g>
  <g>friend</g>
  <c>stuff</c>
  <g>yep</g>
</nodeX>
...

Desired output: 所需的输出:

...
<nodeX>
  <a>words</a>
  <b>things</b>
  <g>hi there friend</g>
  <c>stuff</c>
  <g>yep</g>
</nodeX>
...

I'm working with an extremely complex and varied document with a deep hierarchy, so I can't work with many assumptions beyond the fact that these elements will show up in some context or another, and when they appear with an adjacent sibling, those siblings need to merge. 我正在使用一个具有深层次结构的极其复杂且变化多端的文档,因此除了这些元素将在某个或多个上下文中显示,以及它们与相邻的同级元素一起出现时,我无法进行许多假设。兄弟姐妹需要合并。 Any help would be appreciated. 任何帮助,将不胜感激。

Update: 更新:

Using zx485's & Martin Honnen's advice, the following seems to work well to unwrap only a specific element: 根据zx485和Martin Honnen的建议,以下内容似乎可以很好地解开特定元素:

<xsl:template match="nodeX">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:for-each-group select="*" group-adjacent="name()">
            <xsl:choose>
                <xsl:when test="name()='g'">
                    <xsl:copy>
                        <xsl:copy-of select="current-group()/@*" />
                        <xsl:value-of select="current-group()"/>
                    </xsl:copy>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="current-group()"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

With XSLT-2.0 this is not difficult. 使用XSLT-2.0,这并不困难。 It is an XSLT-2.0 Grouping question. 这是一个XSLT-2.0分组问题。 In this case use xsl:for-each-group with the attribute group-adjacent . 在这种情况下,请将xsl:for-each-groupgroup-adjacent属性一起使用。

The following template matches all nodeX elements and copies them including their attributes. 以下模板匹配所有nodeX元素,并复制它们及其属性。 It iterates over all children and groups adjacent elements by their name() . 它遍历所有子级,并通过它们的name()相邻元素进行分组。 Then it copies the first element of the group and adds the attributes of all elements with the same name. 然后,它复制组中的第一个元素,并添加具有相同名称的所有元素的属性。 Now the text() s of all elements in this group are joined together with a separator - here it's a space. 现在,该组中所有元素的text()都用分隔符连接在一起-这是一个空格。

<xsl:template match="nodeX">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:for-each-group select="*" group-adjacent="name()">
            <xsl:copy>
                <xsl:copy-of select="current-group()/@*" />
                <xsl:value-of select="current-group()" separator=" " />
            </xsl:copy>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template> 

Output is: 输出为:

<nodeX>
   <a>words</a>
   <b>things</b>
   <g>hi there friend</g>
   <c>stuff</c>
   <g>yep</g>
</nodeX>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM