如何使用XSLT对XML文件按节点排序并保留结构(适配InDesign导入)
解决XSLT按
<Last_Name>排序XML并保留结构的问题 嘿,刚接触XSLT确实容易踩这种小坑,我一眼就看出你代码里的问题了——你把<Employee>标签写在了<xsl:for-each>的外面,这就导致所有排序后的员工数据都被塞进同一个<Employee>节点里了!咱们调整一下就能搞定。
你的问题核心
你需要遍历每个<Employee>节点,按<Last_Name>字母排序,并且每个员工都保留自己完整的<Employee>结构,而不是把所有内容合并成一个。
修正后的XSLT代码
这里有两种写法,一种是简洁版(直接复制整个节点),一种是和你原代码逻辑接近的手动复刻版:
简洁版(推荐,减少重复代码)
<?xml version="1.0" encoding="UTF-8"?> <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:template match="/"> <Root> <!-- 遍历所有Employee节点,按Last_Name排序 --> <xsl:for-each select="Root/Employee"> <xsl:sort select="Last_Name" order="ascending" case-order="upper-first"/> <!-- 直接复制当前整个Employee节点及其所有子节点 --> <xsl:copy-of select="."/> </xsl:for-each> </Root> </xsl:template> </xsl:stylesheet>
手动复刻版(和你原代码逻辑对齐)
如果你想手动写出每个子节点,只需要把<Employee>移到for-each里面:
<?xml version="1.0" encoding="UTF-8"?> <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:template match="/"> <Root> <xsl:for-each select="Root/Employee"> <xsl:sort select="Last_Name"/> <!-- 把Employee标签放到循环里,每个员工生成自己的节点 --> <Employee> <First_Name><xsl:value-of select="First_Name"/></First_Name> <Last_Name><xsl:value-of select="Last_Name"/></Last_Name> <Salary><xsl:value-of select="Salary"/></Salary> <Performance><xsl:value-of select="Performance"/></Performance> </Employee> </xsl:for-each> </Root> </xsl:template> </xsl:stylesheet>
关键修正点
- 把
<Employee>标签从for-each外面移到循环内部,这样每次循环都会生成一个独立的<Employee>节点。 - 简洁版用
<xsl:copy-of select="."/>直接复制当前节点的所有内容,避免手动写每个子节点,既高效又不容易出错。 xsl:sort的order和case-order属性可以明确排序规则(默认就是升序,这里写上更清晰)。
运行后输出
就是你期望的结果:
<?xml version="1.0" encoding="UTF-8"?> <Root> <Employee> <First_Name>Donald</First_Name> <Last_Name>Abernathey</Last_Name> <Salary>95000</Salary> <Performance>7</Performance> </Employee> <Employee> <First_Name>Betsy</First_Name> <Last_Name>Clarke</Last_Name> <Salary>105000</Salary> <Performance>10</Performance> </Employee> <Employee> <First_Name>Andrew</First_Name> <Last_Name>Miller</Last_Name> <Salary>100000</Salary> <Performance>8</Performance> </Employee> </Root>
内容的提问来源于stack exchange,提问作者didierCH
相关产品推荐
相关产品推荐

