根据内部元素的 ID 将平面 xml 转换为树层次结构
Posted
技术标签:
【中文标题】根据内部元素的 ID 将平面 xml 转换为树层次结构【英文标题】:Converting a flat xml to a tree hierarchy based on IDs of inner elements 【发布时间】:2021-12-22 22:15:39 【问题描述】:我的起始 XML 包含一个无序的平面目录列表,其中包含一个元素,每个元素都有自己的 ID 和子 ID(如果有的话)。
我的起始 XML 如下所示:
<root>
<catalogue>
<item>
<id>item2</id>
<child>
<id>item3</id>
</child>
</item>
</catalogue>
<catalogue>
<item>
<id>item1</id>
<child>
<id>item2</id>
</child>
</item>
</catalogue>
<catalogue>
<item>
<id>item3</id>
</item>
</catalogue>
</root>
我需要将其转换为嵌套的树层次结构,其中相应的子项写入其父项内。
生成的 XML 应如下所示:
<root>
<catalogue>
<item>
<id>item1</id>
<child>
<id>item2</id>
</child>
</item>
<catalogue>
<item>
<id>item2</id>
<child>
<id>item3</id>
</child>
</item>
<catalogue>
<item>
<id>item3</id>
</item>
</catalogue>
</catalogue>
</catalogue>
</root>
我已经有点接近解决方案了,但我无法让生成的 XML 文件不包含不必要的重复元素。
在以下 XML 文件中,根目录中的顶部和底部目录是重复的不需要的条目。我只需要大而中等的目录。
我当前的结果 XML 如下所示:
<root>
<catalogue>
<item>
<id>item2</id>
<child>
<id>item3</id>
</child>
</item>
<catalogue>
<item>
<id>item3</id>
</item>
</catalogue>
</catalogue>
<catalogue>
<item>
<id>item1</id>
<child>
<id>item2</id>
</child>
</item>
<catalogue>
<item>
<id>item2</id>
<child>
<id>item3</id>
</child>
</item>
<catalogue>
<item>
<id>item3</id>
</item>
</catalogue>
</catalogue>
</catalogue>
<catalogue>
<item>
<id>item3</id>
</item>
</catalogue>
</root>
正在使用此 XSLT 文件创建我当前的结果 XML:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="catalogue">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
<xsl:for-each select="/root/catalogue[item/id/text() = current()/item/child/id/text()]">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我一直试图找到解决这个问题的方法太久了,所以我希望有人能帮助我。
【问题讨论】:
【参考方案1】:可能是这样的:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="cat" match="catalogue" use="item/id" />
<xsl:template match="/root">
<xsl:copy>
<!-- start with items that are not children of any item -->
<xsl:apply-templates select="catalogue[not(item/id = //child/id)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="catalogue">
<xsl:copy>
<xsl:copy-of select="item"/>
<!-- recurse with current item's children -->
<xsl:apply-templates select="key('cat', item/child/id)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
【讨论】:
以上是关于根据内部元素的 ID 将平面 xml 转换为树层次结构的主要内容,如果未能解决你的问题,请参考以下文章