gpt4 book ai didi

xslt-2.0 - 使用 XSLT 基于属性值的平面到嵌套结构

转载 作者:行者123 更新时间:2023-12-04 20:16:51 24 4
gpt4 key购买 nike

我有一个平面结构的 XML 文件,如下所示:

<rs>
<r id="r1" lev="0"/>
<r id="r2" lev="1"/>
<r id="r3" lev="0"/>
<r id="r4" lev="1"/>
<r id="r5" lev="2"/>
<r id="r6" lev="3"/>
<r id="r7" lev="0"/>
<r id="r8" lev="1"/>
<r id="r9" lev="2"/>
</rs>

我需要将其转换为嵌套的。规则就是一切r[number(@lev) gt 0]应该嵌套在 r[number(@lev) eq 0] 内.输出将是这样的:
<rs>
<r id="r1">
<r id="r2"/>
</r>
<r id="r3">
<r id="r4">
<r id="r5">
<r id="r6"/>
</r>
</r>
</r>
<r id="r7">
<r id="r8">
<r id="r9"/>
</r>
</r>
</rs>

我尝试过的是以下转换:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="/">
<rs>
<xsl:apply-templates select="node()|@*"/>
</rs>
</xsl:template>

<xsl:template match="r">
<xsl:variable name="lev" select="number(@lev)" as="xs:double"/>
<r>
<xsl:copy-of select="@id"/>
<xsl:apply-templates select="following-sibling::r[not(number(@lev) eq $lev)
and
count(preceding-sibling::r[number(@lev) eq $lev]) eq 1]"/>
</r>
</xsl:template>

</xsl:stylesheet>

但是,这并没有给我想要的结果。非常感谢指出我的编码错误或任何其他完成工作的方法。

最佳答案

本次改造 :

<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="kRByLevelAndParent" match="r"
use="concat(generate-id(preceding-sibling::r
[not(@lev >= current()/@lev)][1]),
@lev
)"/>

<xsl:template match="/*">
<rs>
<xsl:apply-templates select="key('kRByLevelAndParent', '0')"/>
</rs>
</xsl:template>

<xsl:template match="r">
<r id="{@id}">
<xsl:apply-templates select=
"key('kRByLevelAndParent',
concat(generate-id(), @lev+1)
)"/>
</r>
</xsl:template>
</xsl:stylesheet>

当应用于提供的 XML 文档时:
<rs>
<r id="r1" lev="0"/>
<r id="r2" lev="1"/>
<r id="r3" lev="0"/>
<r id="r4" lev="1"/>
<r id="r5" lev="2"/>
<r id="r6" lev="3"/>
<r id="r7" lev="0"/>
<r id="r8" lev="1"/>
<r id="r9" lev="2"/>
</rs>

产生想要的正确结果:
<rs>
<r id="r1">
<r id="r2"/>
</r>
<r id="r3">
<r id="r4">
<r id="r5">
<r id="r6"/>
</r>
</r>
</r>
<r id="r7">
<r id="r8">
<r id="r9"/>
</r>
</r>
</rs>

说明 :

使用复合键的位置分组——对于它的所有“子元素”,一个元素是第一个前面的兄弟元素,这样它的 lev属性小于它们各自的 lev属性。

关于xslt-2.0 - 使用 XSLT 基于属性值的平面到嵌套结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11113161/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com