从个别记录创建分类结构

时间:2017-04-15 17:01:28

标签: xslt

我对如何有效解决这个问题缺乏想象力。我的实际数据集有成千上万的记录。每条记录都表明其在分类结构中的位置。我需要创建该分类结构并将记录放在该结构中(例如,记录表明它们进入" / a / b / c"最终在" / a / b / c& #34;但每个分类水平只有一个" a"," b"和" c")。由于客户的机密性,我在这里发布了一个天真的代表。

使用XSLT 3是可取的。我知道有一个使用xsl:iterate的解决方案,但我无法弄明白。

输入:

<outer>
    <record>
        <id>rec1</id>
        <taxNodes>
            <node>
                <id>1</id>
                <note>First level</note>
                <node>
                    <id>node2a</id>
                    <note>Second level Entry A</note>
                </node>
            </node>
        </taxNodes>
    </record>
    <record>
        <id>rec3</id>
        <taxNodes>
            <node>
                <id>1</id>
                <note>First level</note>
                <node>
                    <id>node2b</id>
                    <note>Second level Entry B</note>
                </node>
            </node>
        </taxNodes>
    </record>
    <record>
        <id>rec4</id>
        <taxNodes>
            <node>
                <id>1</id>
                <note>First level</note>
                <node>
                    <id>node2b</id>
                    <note>Second level Entry B</note>
                </node>
            </node>
        </taxNodes>
    </record>
</outer>

期望的输出:

<outer>
    <node>
        <id>1</id>
        <note>First level</note>
        <node>
            <id>node2a</id>
            <note>Second level Entry A</note>
            <records>
                <record>
                    <id>rec1</id>
                </record>
            </records>
        </node>
        <node>
            <id>node2b</id>
            <note>Second level Entry B</note>
            <records>
                <record>
                    <id>rec3</id>
                </record>
                <record>
                    <id>rec4</id>
                </record>
            </records>
        </node>
    </node>
</outer>

2 个答案:

答案 0 :(得分:0)

此样式表提供了一个解决方案,但使用循环函数来实现。

update movies 
    set title = 'new title',
        show_start = '16-04-2017',
        show_end = '16-04-2017' 
where id = '1';

答案 1 :(得分:0)

我认为这可以看作是一个分组问题,然后使用xsl:for-each-group的递归函数解决:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="xs math mf"
    version="3.0">

    <xsl:output indent="yes"/>

    <xsl:function name="mf:group" as="node()*">
        <xsl:param name="input-nodes" as="element(node)*"/>
        <xsl:for-each-group select="$input-nodes" group-by="id">
            <xsl:copy>
                <xsl:copy-of select="id, note"/>
                <xsl:choose>
                    <xsl:when test="current-group()/node">
                        <xsl:sequence select="mf:group(current-group()/node)"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <records>
                            <xsl:apply-templates select="current-group()/ancestor::record"/>
                        </records>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:copy>
        </xsl:for-each-group>
    </xsl:function>

    <xsl:template match="outer">
        <xsl:copy>
            <xsl:sequence select="mf:group(record/taxNodes/node)"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="record">
        <xsl:copy>
            <xsl:copy-of select="id"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

这给出了我想对你发布的输入样本所期望的结果,我不确定它会对其他输入做什么,主要是因为我不确定输入的变量是多少,我想如果我理解规范& #39;每个分类水平只有一个&#34; a&#34;,&#34; b&#34;和&#34; c&#34;&#39;正确然后它应该工作正常。

至于拥有一个庞大的输入文件并使用XSLT 3.0(带流媒体?),我不确定流媒体解决方案是否可行,因为问题的本质是我们需要递归地对整个输入集进行分组{ {1}}秒。