我正在尝试使用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>
...
你尚未很清楚地说明问题。我假设如果<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>
未经测试。
对于那个很抱歉。我添加了其他信息并格式化了xml。是的,你是对的。“如果X的<parent>元素包含对Y的<id>的引用,则X在输出中成为Y的子代”。我需要在Level1中没有父项的所有节点,在Level2中需要它们的所有子级,而在Level3中需要Level2的所有子级,依此类推...最终级别仅在关系节点中包含父ID。感谢xslt结构的指导,我不知道关键功能。我会试一试。根据我添加的其他信息,如果我需要考虑其他任何参数,请告诉我。
有效。非常感谢你!