如何使用一些空属性进行 xslt Muenchian 分组? [英] How to do xslt Muenchian grouping with some null attributes?

查看:23
本文介绍了如何使用一些空属性进行 xslt Muenchian 分组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与标准 Meunchain 分组略有不同,因为我正在处理我正在转换的某些标签的 null(?) 属性.我希望将空分组视为它们自己的单独组,转换后的输出添加分组字符串.此外,如果有一个分组来计算有多少.

Slightly different to the standard Meunchain grouping as I'm dealing with a null(?) attribute for some of the tags that I'm transforming. I'd like the null groupings to be treated as their own individual group with the transformed output adding the grouped strings. Also if there is a grouping to do a count of how many there were.

<root>
<section>
    <subsection>
        <module>
            <comp>111</comp>
        </module>
        <module group='group01'>
            <comp>222</comp>
        </module>
        <module group='group01'>
            <comp>333</comp>
        </module>
        <module>
            <comp>444</comp>
        </module>
        <module>
            <comp>555</comp>
        </module>
    </subsection>
</section>
<section>
    <subsection>
        <module group ="group02">
            <comp>666</comp>
        </module>
        <module group ="group02">
            <comp>777</comp>
        </module>
        <module>
            <comp>888</comp>
        </module>
        <module group ="group03">
            <comp>999</comp>
        </module>
        <module group ="group03">
            <comp>101010</comp>
        </module>
    </subsection>
    <subsection>
        <module group ="group04">
            <comp>11111</comp>
        </module>
        <module group ="group04">
            <comp>121212</comp>
        </module>
        <module group ="group05">
            <comp>131313</comp>
        </module>
        <module group ="group05">
            <comp>141414</comp>
        </module>
        <module group ="group06">
            <comp>151515</comp>
        </module>
        <module group ="group06">
            <comp>161616</comp>
        </module>
        <module>
            <comp>171717</comp>
        </module>
    </subsection>
</section>

想要的输出:

<AllSections>
<section>
    <subsection>
        <page>
            <content>111</content>
        </page>
        <page>
            <content>222333</content>
            <count>2</count>
        </page>
        <page>
            <content>444</content>
        </page>
        <page>
            <content>555</content>
        </page>
    </subsection>
</section>
<section>
    <subsection>
        <page>
            <content>666777</content>
            <count>2</count>
        </page>
        <page>
            <content>888</content>
        </page>
        <page>
            <content>999101010</content>
            <count>2</count>
        </page>
    </subsection>
    <subsection>
        <page>
            <content>111111121212</content>
            <count>2</count>
        </page>
        <page>
            <content>131313141414161616</content>
            <count>3</count>
        </page>
        <page>
            <content>151515</content>
        </page>
        <page>
            <content>171717</content>
        </page>
    </subsection>
</section>

谢谢!

推荐答案

对于具有 group 属性的元素,您按该属性分组,但也在父 subsection 元素.因此,您可以通过定义一个键来将它们分组,这是

For the elements with a group attribute, you are grouping by that attribute but also within the parent subsection element. Therefore you could start off by defining a key to group them this was

<xsl:key name="modules" match="module[@group]" use="concat(generate-id(..), '|', @group)" />

接下来,您需要模板来匹配 module 元素的各种情况.首先,您可以有一个模板来匹配没有 group 属性的 module 元素,您可以在其中根据需要格式化输出.

Next, you would need templates to match the various cases for the module elements. Firstly, you could have a template to match module elements with no group attribute, where you could format the output as required.

<xsl:template match="module[not(@group)]">
    <page>
        <content>
            <xsl:value-of select="comp"/>
        </content>
    </page>
 </xsl:template>

对于具有 group 属性的模块,您需要匹配以检查此特定 module 元素是否首先出现在上面定义的键的组中.

For modules, with group attributes you would need a match that checked that this particular module element occurred first in the group for the key defined above.

<xsl:template 
  match="module
    [@group]
    [generate-id() = generate-id(key('modules', concat(generate-id(..), '|', @group))[1])]">

在这个模板中,您可以轻松地定义一个变量来保存组中的元素,使用键,然后输出子comp元素,或者对它们进行计数

Within this template, you could then easily define a variable to hold the elements in the group, using the key, and then either output the child comp elements, or count them

<xsl:variable name="modules" select="key('modules', concat(generate-id(..), '|', @group))"/>
<page>
    <content>
        <xsl:apply-templates select="$modules/comp/text()"/>
    </content>
    <count>
        <xsl:value-of select="count($modules)" />
     </count>
</page>

最后,您需要第三个模板来匹配所有其他 module 元素(即具有 group 属性的元素,但不是组中的第一个)以忽略它们,以确保他们不会获得两次输出.(XSLT 处理器应该总是在这个更通用的模板之前匹配更具体的模板)

Finally, you would need a third template to match all other module elements (i.e. elements with a group attribute, but not first in the group) to ignore them, to ensure they don't get output twice. (The XSLT processor should always match more specific templates before this more generic one)

<xsl:template match="module"/>

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="modules" match="module[@group]" use="concat(generate-id(..), '|', @group)"/>

    <xsl:template match="root">
        <AllSections>
            <xsl:apply-templates />
        </AllSections>
    </xsl:template>

    <xsl:template match="module[not(@group)]">
        <page>
            <content>
                <xsl:value-of select="comp"/>
            </content>
        </page>
    </xsl:template>

    <xsl:template match="module[@group][generate-id() = generate-id(key('modules', concat(generate-id(..), '|', @group))[1])]">
        <xsl:variable name="modules" select="key('modules', concat(generate-id(..), '|', @group))"/>
        <page>
            <content>
                <xsl:apply-templates select="$modules/comp/text()"/>
            </content>
            <count>
                <xsl:value-of select="count($modules)" />
            </count>
        </page>
    </xsl:template>

    <xsl:template match="module"/>

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

当应用于您的示例 XML 时,输出如下

When applied to your sample XML, the following is output

<AllSections>
    <section>
        <subsection>
            <page>
                <content>111</content>
            </page>
            <page>
                <content>222333</content>
                <count>2</count>
            </page>
            <page>
                <content>444</content>
            </page>
            <page>
                <content>555</content>
            </page>
        </subsection>
    </section>
    <section>
        <subsection>
            <page>
                <content>666777</content>
                <count>2</count>
            </page>
            <page>
                <content>888</content>
            </page>
            <page>
                <content>999101010</content>
                <count>2</count>
            </page>
        </subsection>
        <subsection>
            <page>
                <content>11111121212</content>
                <count>2</count>
            </page>
            <page>
                <content>131313141414</content>
                <count>2</count>
            </page>
            <page>
                <content>151515161616</content>
                <count>2</count>
            </page>
            <page>
                <content>171717</content>
            </page>
        </subsection>
    </section>
</AllSections>

这篇关于如何使用一些空属性进行 xslt Muenchian 分组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆