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

发布于 2024-11-05 21:01:38 字数 1698 浏览 0 评论 0原文

我试图将元素组拆分为包含一组唯一元素的组,同时维护拆分中的所有兄弟关系。例如,我希望将以下 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>

编辑:初始数据中的第一组具有重复元素。例如,元素 出现两次。我希望第二次出现的 位于结果中的新组中。这就是我所说的独特的集合。

编辑 #2:忘记提及当第二个 被拉出到自己的组中时,它的同级 也会被“复制”。这就是我说的保留兄弟姐妹的意思。

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

不幸的是,我是 XSLT 新手,但我尝试应用 XSLT 在后代节点处分割树在 xml 层次结构中向上移动分隔符元素,因为它们看起来非常接近我的内容我正在努力实现。

我正在使用 1.0 – 2.0 对我来说不是一个选择。任何帮助将不胜感激。

I am trying to split groups of elements into groups that contain a unique set of elements while maintaining all sibling relationships in the split. For instance, I’d like the following 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>

To be transformed to:

<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>

EDIT: The first group in the initial data has duplicate elements. For example the element <b075> occurs twice. I would like for the second occurrence of <b075> to be in a new group in the result. That's what I meant by unique set.

EDIT #2: Forgot to mention that when the second <b075> is pulled out into its own group, its sibling <b074> is "copied" along. That's what i meant by keeping the siblings.

EDIT #3: (I apologize, I should have explained this more thoroughly the first time) The way you know that <b074> belongs in the resulting group is because it occurs once. All elements in the original group that occur once are shared by all the resulting groups. The repeating elements are also going to be listed sequentially, meaning if elements <b075> and <b076> repeat, they will be next to each other, <b075>, then immediately <b076>. So the number of resulting groups, is the number of such repeating chunks of elements (2 in the case of this example).

Unfortunately, I am new to XSLT, but I have attempted unsuccessfully to apply variations of the solutions found at XSLT split a tree at a descendent node and Move separator elements upwards in xml hierarchy, as they seem very close to what I am trying to accomplish.

I am using 1.0 – 2.0 is not an option for me. Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

毁我热情 2024-11-12 21:01:38

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

<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 ] ) <= $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>

If i understand your conditions right, following transformation is what you want:

<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 ] ) <= $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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文