xslt - XSLT:按 ID 分组的无序平面 XML 到层次结构
问题描述
我正在努力使用 XSLT 1.0 创建一个转换,以按其 GUID 分层呈现我的数据。我有一个平面 XML,其中包含有关文件夹及其文件的数据,无序。我想以树形结构呈现这些数据。
平面 XML 无序:
<tns:Response>
<tns:Result>
<tns:ChildFolder>
<tns:fFolderGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</tns:fFolderGUID>
<tns:fParentGUID>F050669AEA220E5B6D32FB92ABDB0080</tns:fParentGUID>
<tns:fFolderName>Folder 0</tns:fFolderName>
<tns:ChildFolder>
<tns:fFolderGUID>91FEE5D69B8ABCE6DBEDE95344D962CE</tns:fFolderGUID>
<tns:fParentGUID>D5F39DA59300A125437090D6E1A8BA89</tns:fParentGUID>
<tns:fFolderName>Folder 5</tns:fFolderName>
</tns:ChildFolder>
<tns:ChildFolder>
<tns:fFolderGUID>13A6EB7420E7586B21CC8F9CCED8AAA5</tns:fFolderGUID>
<tns:fParentGUID>91FEE5D69B8ABCE6DBEDE95344D962CE</tns:fParentGUID>
<tns:fFolderName>Folder 6</tns:fFolderName>
</tns:ChildFolder>
<tns:ChildFolder>
<tns:fFolderGUID>99964626C187728B8A0823564126D091</tns:fFolderGUID>
<tns:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</tns:fParentGUID>
<tns:fFolderName>Folder 1</tns:fFolderName>
</tns:ChildFolder>
<tns:ChildFolder>
<tns:fFolderGUID>FEAD438C243F2AB6D3F273D4BBE701C3</tns:fFolderGUID>
<tns:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</tns:fParentGUID>
<tns:fFolderName>Folder 2</tns:fFolderName>
</tns:ChildFolder>
<tns:ChildFolder>
<tns:fFolderGUID>0F2F52149628A0029C436500873A1F1F</tns:fFolderGUID>
<tns:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</tns:fParentGUID>
<tns:fFolderName>Folder 3</tns:fFolderName>
</tns:ChildFolder>
<tns:ChildFolder>
<tns:fFolderGUID>D5F39DA59300A125437090D6E1A8BA89</tns:fFolderGUID>
<tns:fParentGUID>99964626C187728B8A0823564126D091</tns:fParentGUID>
<tns:fFolderName>Folder 4</tns:fFolderName>
</tns:ChildFolder>
<tns:ChildFile>
<tns:fFileGUID>68E2DB7C43ED0C4C14D902398AD494FC</tns:fFileGUID>
<tns:fParentGUID>D5F39DA59300A125437090D6E1A8BA89</tns:fParentGUID>
<tns:dDocTitle>Document 4 - 1</tns:dDocTitle>
</tns:ChildFile>
<tns:ChildFile>
<tns:fFileGUID>15D8716AAACDAEFDCBA77434BF62649D</tns:fFileGUID>
<tns:fParentGUID>FEAD438C243F2AB6D3F273D4BBE701C3</tns:fParentGUID>
<tns:dDocTitle>Document 2 - 2</tns:dDocTitle>
</tns:ChildFile>
<tns:ChildFile>
<tns:fFileGUID>8DB55ACDC7518F0C2062456B0B467375</tns:fFileGUID>
<tns:fParentGUID>FEAD438C243F2AB6D3F273D4BBE701C3</tns:fParentGUID>
<tns:dDocTitle>Document 2 - 1</tns:dDocTitle>
</tns:ChildFile>
<tns:ChildFile>
<tns:fFileGUID>AD7476CEF93E5C2A9F69DAFE6D42066D</tns:fFileGUID>
<tns:fParentGUID>13A6EB7420E7586B21CC8F9CCED8AAA5</tns:fParentGUID>
<tns:dDocTitle>Document 6 - 2</tns:dDocTitle>
</tns:ChildFile>
<tns:ChildFile>
<tns:fFileGUID>00011D503C2691173A8A2C3004E9BE4E</tns:fFileGUID>
<tns:fParentGUID>13A6EB7420E7586B21CC8F9CCED8AAA5</tns:fParentGUID>
<tns:dDocTitle>Document 6 - 1</tns:dDocTitle>
</tns:ChildFile>
<tns:ChildFile>
<tns:fFileGUID>CE82CD61E4D913817C3C795F1403C621</tns:fFileGUID>
<tns:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</tns:fParentGUID>
<tns:dDocTitle>Document 0 - 1</tns:dDocTitle>
</tns:ChildFile>
<tns:ChildFile>
<tns:fFileGUID>65DB227672A92D4DB1F153EB5EF5D41B</tns:fFileGUID>
<tns:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</tns:fParentGUID>
<tns:dDocTitle>Document 0 - 2</tns:dDocTitle>
</tns:ChildFile>
<tns:ChildFile>
<tns:fFileGUID>2099C99CE0B1BE9FA5A7152F21F23330</tns:fFileGUID>
<tns:fParentGUID>99964626C187728B8A0823564126D091</tns:fParentGUID>
<tns:dDocTitle>Document 1 - 1</tns:dDocTitle>
</tns:ChildFile>
<tns:ChildFile>
<tns:fFileGUID>32F8C5F47475A093D1AE748552AD1A21</tns:fFileGUID>
<tns:fParentGUID>99964626C187728B8A0823564126D091</tns:fParentGUID>
<tns:dDocTitle>Document 1 - 2</tns:dDocTitle>
</tns:ChildFile>
</tns:ChildFolder>
我希望它在树结构中进行排序,如下所示:
<ns0:Response>
<ns0:Result>
<ns0:ChildFolder>
<ns0:fFolderGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</ns0:fFolderGUID>
<ns0:fParentGUID>F050669AEA220E5B6D32FB92ABDB0080</ns0:fParentGUID>
<ns0:fFolderName>Folder 0</ns0:fFolderName>
<ns0:ChildFile>
<ns0:fFileGUID>CE82CD61E4D913817C3C795F1403C621</ns0:fFileGUID>
<ns0:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</ns0:fParentGUID>
<ns0:dDocTitle>Document 0 - 1</ns0:dDocTitle>
</ns0:ChildFile>
<ns0:ChildFile>
<ns0:fFileGUID>65DB227672A92D4DB1F153EB5EF5D41B</ns0:fFileGUID>
<ns0:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</ns0:fParentGUID>
<ns0:dDocTitle>Document 0 - 2</ns0:dDocTitle>
</ns0:ChildFile>
<ns0:ChildFolder>
<ns0:fFolderGUID>99964626C187728B8A0823564126D091</ns0:fFolderGUID>
<ns0:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</ns0:fParentGUID>
<ns0:fFolderName>Folder 1</ns0:fFolderName>
<ns0:ChildFile>
<ns0:fFileGUID>2099C99CE0B1BE9FA5A7152F21F23330</ns0:fFileGUID>
<ns0:fParentGUID>99964626C187728B8A0823564126D091</ns0:fParentGUID>
<ns0:dDocTitle>Document 1 - 1</ns0:dDocTitle>
</ns0:ChildFile>
<ns0:ChildFile>
<ns0:fFileGUID>32F8C5F47475A093D1AE748552AD1A21</ns0:fFileGUID>
<ns0:fParentGUID>99964626C187728B8A0823564126D091</ns0:fParentGUID>
<ns0:dDocTitle>Document 1 - 2</ns0:dDocTitle>
</ns0:ChildFile>
<ns0:ChildFolder>
<ns0:fFolderGUID>D5F39DA59300A125437090D6E1A8BA89</ns0:fFolderGUID>
<ns0:fParentGUID>99964626C187728B8A0823564126D091</ns0:fParentGUID>
<ns0:fFolderName>Folder 4</ns0:fFolderName>
<ns0:ChildFile>
<ns0:fFileGUID>68E2DB7C43ED0C4C14D902398AD494FC</ns0:fFileGUID>
<ns0:fParentGUID>D5F39DA59300A125437090D6E1A8BA89</ns0:fParentGUID>
<ns0:dDocTitle>Document 4 - 1</ns0:dDocTitle>
</ns0:ChildFile>
<ns0:ChildFolder>
<ns0:fFolderGUID>91FEE5D69B8ABCE6DBEDE95344D962CE</ns0:fFolderGUID>
<ns0:fParentGUID>D5F39DA59300A125437090D6E1A8BA89</ns0:fParentGUID>
<ns0:fFolderName>Folder 5</ns0:fFolderName>
<ns0:ChildFolder>
<ns0:fFolderGUID>13A6EB7420E7586B21CC8F9CCED8AAA5</ns0:fFolderGUID>
<ns0:fParentGUID>91FEE5D69B8ABCE6DBEDE95344D962CE</ns0:fParentGUID>
<ns0:fFolderName>Folder 6</ns0:fFolderName>
<ns0:ChildFile>
<ns0:fFileGUID>AD7476CEF93E5C2A9F69DAFE6D42066D</ns0:fFileGUID>
<ns0:fParentGUID>13A6EB7420E7586B21CC8F9CCED8AAA5</ns0:fParentGUID>
<ns0:dDocTitle>Document 6 - 2</ns0:dDocTitle>
</ns0:ChildFile>
<ns0:ChildFile>
<ns0:fFileGUID>00011D503C2691173A8A2C3004E9BE4E</ns0:fFileGUID>
<ns0:fParentGUID>13A6EB7420E7586B21CC8F9CCED8AAA5</ns0:fParentGUID>
<ns0:dDocTitle>Document 6 - 1</ns0:dDocTitle>
</ns0:ChildFile>
</ns0:ChildFolder>
</ns0:ChildFolder>
</ns0:ChildFolder>
</ns0:ChildFolder>
<ns0:ChildFolder>
<ns0:fFolderGUID>FEAD438C243F2AB6D3F273D4BBE701C3</ns0:fFolderGUID>
<ns0:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</ns0:fParentGUID>
<ns0:fFolderName>Folder 2</ns0:fFolderName>
<ns0:ChildFile>
<ns0:fFileGUID>15D8716AAACDAEFDCBA77434BF62649D</ns0:fFileGUID>
<ns0:fParentGUID>FEAD438C243F2AB6D3F273D4BBE701C3</ns0:fParentGUID>
<ns0:dDocTitle>Document 2 - 2</ns0:dDocTitle>
</ns0:ChildFile>
<ns0:ChildFile>
<ns0:fFileGUID>8DB55ACDC7518F0C2062456B0B467375</ns0:fFileGUID>
<ns0:fParentGUID>FEAD438C243F2AB6D3F273D4BBE701C3</ns0:fParentGUID>
<ns0:dDocTitle>Document 2 - 1</ns0:dDocTitle>
</ns0:ChildFile>
</ns0:ChildFolder>
<ns0:ChildFolder>
<ns0:fFolderGUID>0F2F52149628A0029C436500873A1F1F</ns0:fFolderGUID>
<ns0:fParentGUID>F3CF39082F7CD2DC9AAD9E34D6BFDA84</ns0:fParentGUID>
<ns0:fFolderName>Folder 3</ns0:fFolderName>
</ns0:ChildFolder>
</ns0:ChildFolder>
</ns0:Result>
</ns0:Response>
目前我正在使用 for-eaches 来测试文件夹/文件是否是父文件夹的子文件夹以及一个保存每个级别位置的变量。这样我只能呈现有限数量的关卡。必须有可能以更简单的方式做到这一点。感谢您帮助社区!
解决方案
定义一个或两个键来跟随 id 引用,然后处理/应用模板到所有引用的孩子:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tns="http://example.com/tns"
exclude-result-prefixes="tns"
version="1.0">
<xsl:key name="child-files" match="tns:ChildFile" use="tns:fParentGUID"/>
<xsl:key name="child-folders" match="tns:ChildFolder" use="tns:fParentGUID"/>
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tns:ChildFolder">
<xsl:copy>
<xsl:apply-templates select="tns:*[not(self::tns:ChildFolder | self::tns:ChildFile)]"/>
<xsl:apply-templates select="key('child-files', tns:fFolderGUID)"/>
<xsl:apply-templates select="key('child-folders', tns:fFolderGUID)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/gWmuiJt有一个在线示例。由于键适用于整个文档,如果用于键值的 id 在整个文档中不是唯一的并且有多个具有相同 id 的文件夹,则此方法将不起作用。但由于这些值似乎是 GUID,我猜你有独特的值。
推荐阅读
- iphone - 在 xcode 中构建时保持 iphone 解锁
- regex - perl 正则表达式仅替换字符串之外
- angular - 延迟加载模块的路由完全重新加载应用程序
- wpf - 自定义窗口拖动处理程序干扰滚动查看器栏拖动
- azure - 如果积压日志中有 x 数量的错误项,我如何创建某种策略来拒绝拉取请求
- python-3.x - 在 Python 中生成字符串时,如何将字符串注入 shell 脚本?
- sql-server - 使用来自同一个表的子查询更新表列(移动平均)
- docker - 竹码头建设失败?
- c# - 使用不同用户创建进程时,进程需要提升
- pine-script - 买/卖订单的执行订单