xml - XSLT 将重复元素拆分为单独的组,同时保留同级元素

标签 xml xslt

我试图将元素组拆分为包含一组唯一元素的组,同时维护拆分中的所有兄弟关系。例如,我想要以下 xml:

<group>
    <b074>11</b074>
    <b075>03</b075>
    <b076>9</b076>
    <b075>04</b075>
    <b076>12</b076>
</group>
<group>
    <b074>11</b074>
    <b075>04</b075>
    <b076>4</b076>
</group>

要转换为:

<group>
    <b074>11</b074>
    <b075>03</b075>
    <b076>9</b076>
</group>
<group>
    <b074>11</b074>
    <b075>04</b075>
    <b076>12</b076>
</group>
<group>
    <b074>11</b074>
    <b075>04</b075>
    <b076>4</b076>
</group>

编辑:初始数据中的第一组具有重复元素。例如元素 <b075>出现两次。我想要第二次出现 <b075>在结果中属于一个新组。这就是我所说的独特集的意思。

编辑#2:忘记提及当第二个<b075>时被拉出到它自己的组中,即它的兄弟组 <b074>一起“复制”。这就是我所说的保留 sibling 的意思。

编辑#3:(我很抱歉,我应该第一次更彻底地解释这一点)你知道的方式<b074>属于结果组是因为它出现一次。原始组中出现一次的所有元素都由所有结果组共享。重复元素也将按顺序列出,这意味着如果元素 <b075><b076>重复一遍,它们将彼此相邻,<b075> ,然后立即<b076> 。因此,结果组的数量就是此类重复元素 block 的数量(在本示例中为 2)。

不幸的是,我是 XSLT 新手,但我尝试应用 XSLT split a tree at a descendent node 中找到的解决方案的变体,但没有成功。和 Move separator elements upwards in xml hierarchy ,因为它们看起来非常接近我想要实现的目标。

我正在使用 1.0 – 2.0 不适合我。任何帮助将不胜感激。

最佳答案

如果我理解你的条件正确,以下转换就是你想要的:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="group">
        <xsl:apply-templates select="*[1]" mode="group"/>
    </xsl:template>

    <xsl:template match="*" mode="group">
        <xsl:param name="level" select="0"/>
        <xsl:variable name="name" select="name()"/>
        <xsl:variable name="needs-group" select="count( preceding-sibling::*[ name() = $name ] ) = $level"/>
        <xsl:if test="$needs-group">
            <group>
                <xsl:apply-templates select="preceding-sibling::*[ name() != $name ]" mode="item-group">
                    <xsl:with-param name="level" select="$level"/>
                </xsl:apply-templates>

                <xsl:apply-templates select="."/>

                <xsl:apply-templates select="following-sibling::*[ name() != $name ]" mode="item-group">
                    <xsl:with-param name="level" select="$level"/>
                </xsl:apply-templates>
            </group>
        </xsl:if>

        <xsl:apply-templates select="following-sibling::*[1]" mode="group">
            <xsl:with-param name="level" select="$level + $needs-group"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="*" mode="item-group">
        <xsl:param name="level"/>
        <xsl:variable name="name" select="name()"/>
        <xsl:if test="( count( preceding-sibling::*[ name() = $name ] ) = $level ) or ( count( ../*[ name() = $name ] ) &lt;= $level and not( following-sibling::*[ name() = $name ] ) )">
            <xsl:apply-templates select="."/>
        </xsl:if>
    </xsl:template>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

关于xml - XSLT 将重复元素拆分为单独的组,同时保留同级元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5907118/

相关文章:

java - 允许用户上传文件

xml - 使用 XSL 转换标签序列

java - 为 XPath 评估设置当前节点

c# - 根据 DTD 验证 XML - 未找到预期的标记

javascript - 使用 Javascript 修改 XML 元素(在 XSLT 样式表中)

xslt - xslt 中的 cdata for html

xslt - 结果树片段背后的基本原理是什么?

xml - xslt 结果文档覆盖或跳过具有重复 uri 的文件

xml - Powershell选择XML节点,其中属性包含在数组中

xml - 在 Perl 中构建 XML 文件 : Relationship between createAttribute and addChild