Warm tip: This article is reproduced from serverfault.com, please click

其他-XSLT:如何使用XSLT将xml数据转换为分层结构

(其他 - XSLT: How to transform the xml data into a hierarchical structure using XSLT)

发布于 2020-11-28 16:46:56

我正在尝试使用XSLT从平面XML文件创建分层XML文件,并且不确定最好的方法是什么。

XML具有要处理的数据元素,每个数据元素具有“属性”和“关系”。属性-包含与当前数据有关的信息。关系-包含与子元素(对象)和父ID相关的信息。

如果没有元素的父ID,则必须将数据分组为Level 1,并将后续的子元素分组为Level2,依此类推...下面我提供的示例包含数据和直到4级的关系。实际的xml包含更多级别。我尝试了for-each和select函数的组合,但我只能达到两个级别。感谢你是否可以通过XSLT帮助我转换xml以获得完整级别。提前致谢!

输入XML:

<results>
    <content>
        <data>
            <id>12345</id>
            <properties>
                <name>ABC</name>
                <date>2020-07-18</date>
            </properties>
            <relations>
                <object>
                    <data>
                        <id>67890</id>
                    </data>
                </object>
            </relations>
        </data>

        <data>
            <id>67890</id>
            <properties>
                <name>XYZ</name>
                <date>2020-07-18</date>
            </properties>
            <relations>
                <object>
                    <data>
                        <id>22246</id>
                    </data>
                </object>
                <parent>
                    <data>
                        <id>12345</id>
                    </data>
                </parent>
            </relations>
        </data>

        <data>
            <id>22246</id>
            <properties>
                <name>DEF</name>
                <date>2020-07-18</date>
            </properties>
            <relations>
                <object>
                    <data>
                        <id>68681</id>
                    </data>
                </object>
                <parent>
                    <data>
                        <id>67890</id>
                    </data>
                </parent>
            </relations>
        </data>

        <data>
            <id>68681</id>
            <properties>
                <name>UVW</name>
                <date>2020-07-18</date>
            </properties>
            <relations>
                <parent>
                    <data>
                        <id>22246</id>
                    </data>
                </parent>
            </relations>
        </data>
    <content>
</results>

预期产量:

<results>
    <content>
        <Level>
            <id>12345</id>
            <properties>
                <name>ABC</name>
                <date>2020-07-18</date>
            </properties>
            <relations>
                <object>
                    <data>
                        <id>67890</id>
                    </data>
                </object>
            </relations>
            
            <Leve2>
                <id>67890</id>
                <properties>
                    <name>XYZ</name>
                    <date>2020-07-18</date>
                </properties>
                <relations>
                    <object>
                        <data>
                            <id>22246</id>
                        </data>
                    </object>
                    <parent>
                        <data>
                            <id>12345</id>
                        </data>
                    </parent>
                </relations>
                
                <Leve3>
                    <id>22246</id>
                    <properties>
                        <name>DEF</name>
                        <date>2020-07-18</date>
                    </properties>
                    <relations>
                        <object>
                            <data>
                                <id>68681</id>
                            </data>
                        </object>
                        <parent>
                            <data>
                                <id>67890</id>
                            </data>
                        </parent>
                    </relations>
                    
                    <Leve4>
                        <id>68681</id>
                        <properties>
                            <name>UVW</name>
                            <date>2020-07-18</date>
                        </properties>
                        <relations>
                            <parent>
                                <data>
                                    <id>22246</id>
                                </data>
                            </parent>
                        </relations>
                    </Leve4>
                </Leve3>
            </Leve2>
        </Level>        
    <content>
</results>

等级制度:

<Level1>
    Parent1
    <Level2>
        Child1
        ...
        <Level3>
            Child1a
            ...
            <Level4>
                Child1aa
                ...
            </Level4>
        </Level3>
    </Level2>
<Level1>

<Level1>
    Parent2
    <Level2>
        Child2
        ...
        <Level3>
            Child2a
            ...
            <Level4>
                Child2aa
                ...
            </Level4>
        </Level3>
    </Level2>
<Level>
...
Questioner
Shashank G
Viewed
1
Michael Kay 2020-11-29 04:27:16

你尚未很清楚地说明问题。我假设如果<parent>X元素包含<id>对Y的引用,则你希望X在输出中成为Y的子代。(如果我没错,那就是问题所在,那么你的数据就会混乱很多与问题无关的令人困惑的东西,只是分散了对问题的理解)。

在此假设下,首先定义一个键,使找到给定父项的项变得容易:

<xsl:key name =“ parent-key” match =“ content / data” use =“ relations / parent / object / id” />

然后,当你处理一条记录时,只需使用key()函数来获取其子项:

<xsl:template match="content/data">
  <xsl:param name="level" select="1"/>
  <xsl:element name="Level{$level}">
    <xsl:copy-of select="."/>
    <xsl:apply-templates select="key('parent-key', id)">
      <xsl:with-param name="level" select="$level + 1"/>
    </xsl:apply-templates>
  </xsl:element>
</xsl:template>

然后从最高级别的元素开始处理(在你的示例中,这是第一个,我不知道是否总是这样)

<xsl:template match="/">
  <results>
    <content>
      <xsl:apply-templates select="data[1]"/>
    </content>
  </results>
</xsl:template>

未经测试。