对XML进行分组的分组

时间:2018-01-08 15:05:46

标签: xml xslt

我正在尝试在XSL中进行一些分组。能够做一些。它检查SuperParent并搜索所有相同的SuperParent块并将它们组合在一起。可以在此处找到转换:Grouping by Super Parent

但是想知道我们是否可以做下面的事情,我需要一种方法来显示Date,SuperParent,Id&仅与SuperParent和Id相同的元素处于相同级别的阶段。

输入:

val finalDF = df.rdd.zipWithIndex().map(row => (row._1(0).toString, row._1(1).toString, (row._2+1).toInt)).toDF("src_ip", "src_ip_count", "row_number")

必需的输出:

<response status="200">
<ElementList>
    <Element>
        <Date>2017-12-18</Date>
        <SuperParent>1462682</SuperParent>
        <Id>1462682</Id>
        <Status>Completed</Status>
    </Element>
    <Element>
        <Date>2017-12-16</Date>
        <SuperParent>1462682</SuperParent>
        <Id>1462683</Id>
        <Status>Normal</Status>
    </Element>
    <Element>
        <Date>2017-12-15</Date>
        <SuperParent>1462682</SuperParent>
        <Id>1462687</Id>
        <Status>Normal</Status>
    </Element>
    <Element>
        <Date>2017-12-19</Date>
        <SuperParent>1462812</SuperParent>
        <Id>1462812</Id>
        <Status>Normal</Status>
    </Element>
    <Element>
        <Date>2017-12-18</Date>
        <SuperParent>1462812</SuperParent>
        <Id>1462813</Id>
        <Status>Normal</Status>
    </Element>
    <Element>
        <Date>2017-12-17</Date>
        <SuperParent>1462812</SuperParent>
        <Id>1462817</Id>
        <Status>Normal</Status>
    </Element>
</ElementList>

根据请求添加xsltransform.net XSLT。

<ElementList>
<superparent id="1462682">
    <Date>2017-12-18</Date>
    <SuperParent>1462682</SuperParent>
    <Id>1462682</Id>
    <Status>Completed</Status>
    <element>
        <SuperParent>1462682</SuperParent>
        <Id>1462683</Id>
        <Status>Normal</Status>
    </element>
    <element>
        <SuperParent>1462682</SuperParent>
        <Id>1462687</Id>
        <Status>Normal</Status>
    </element>
</superparent>

<superparent id="1462812">
    <Date>2017-12-19</Date>
    <SuperParent>1462812</SuperParent>
    <Id>1462812</Id>
    <Status>Normal</Status>
    <element>
        <SuperParent>1462812</SuperParent>
        <Id>1462813</Id>
        <Status>Normal</Status>
    </element>
    <element>
        <SuperParent>1462812</SuperParent>
        <Id>1462817</Id>
        <Status>Normal</Status>
    </element>
</superparent>

其中给出了以下输出:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="groupBySuperParent" match="Element" use="SuperParent"/>
<xsl:template match="/*">
    <ElementList>
        <xsl:apply-templates/>
    </ElementList>
</xsl:template>
<xsl:template match= "Element[generate-id()=generate-id(key('groupBySuperParent',SuperParent)[1])]">
    <superparent id="{SuperParent}">
        <xsl:copy-of select="key('groupBySuperParent',SuperParent)"/>
    </superparent>
</xsl:template>
<xsl:template match= "Element[not(generate-id()=generate-id(key('groupBySuperParent',SuperParent)[1]))]"/>

2 个答案:

答案 0 :(得分:1)

您可以像以前一样进行分组,但是您需要确保根据Id和SuperParent之间的条件选择并处理每个组中的元素:

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

<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:key name="groupBySuperParent" match="Element" use="SuperParent"/>

<xsl:template match="/*">
    <ElementList>
        <xsl:apply-templates/>
    </ElementList>
</xsl:template>

<xsl:template match= "Element[generate-id()=generate-id(key('groupBySuperParent', SuperParent)[1])]">
    <superparent id="{SuperParent}">
        <xsl:variable name="group" select="key('groupBySuperParent', SuperParent)"/>
        <xsl:copy-of select="$group[Id = SuperParent]/Date | $group[Id = SuperParent]/SuperParent | $group[Id = SuperParent]/Id | $group[Id = SuperParent]/Phase"/>
        <xsl:apply-templates select="$group[not(Id = SuperParent)]" mode="change"/>
    </superparent>
</xsl:template>

<xsl:template match="Element[not(generate-id()=generate-id(key('groupBySuperParent', SuperParent)[1]))]"/>

<xsl:template match="Element" mode="change">
    <xsl:copy>
        <xsl:copy-of select="SuperParent | Id | Status"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

http://xsltfiddle.liberty-development.net/6qM2e29/2

答案 1 :(得分:0)

考虑使用xsl:for-each的Muenchian分组,省略第一个位置元素节点和任何非 Date 子节点。另外,请确保包含<xsl:strip-space element="*"/>以从源XML中删除已保存的换行符/空格。

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="groupBySuperParent" match="Element" use="SuperParent"/>

    <xsl:template match="/response/*">
        <ElementList>
            <xsl:apply-templates select="Element[generate-id()=generate-id(key('groupBySuperParent',SuperParent)[1])]"/>
        </ElementList>
    </xsl:template>

    <xsl:template match= "Element">
        <superparent id="{SuperParent}">
            <xsl:copy-of select="*[name()!='Date']"/>
                <xsl:for-each select="key('groupBySuperParent',SuperParent)">
                    <xsl:if test="position() &gt; 1">
                        <element>
                            <xsl:copy-of select="*[name()!='Date']"/>
                        </element>  
                    </xsl:if>                   
                </xsl:for-each>         
        </superparent>
    </xsl:template>

</xsl:stylesheet>

XSLTransform.Net Demo