求助:使用XSLT进行值比较——对比两个父节点
提取XML中Base和Sub节点的不重复Student_ID元素
需求:现有包含Base和Sub两个父节点的XML文件,需要编写XSLT提取这两个节点里不重复的Student_ID元素。
输入XML
<?xml version="1.0" encoding="UTF-8"?> <Data> <Base> <Student_ID>1234</Student_ID> <Student_ID>1267</Student_ID> <Student_ID>1890</Student_ID> <Student_ID>5678</Student_ID> <Student_ID>6743</Student_ID> <Student_ID>8743</Student_ID> </Base> <Sub> <Student_ID>5678</Student_ID> <Student_ID>6743</Student_ID> <Student_ID>3226</Student_ID> <Student_ID>8123</Student_ID> </Sub> </Data>
预期输出XML
<?xml version="1.0" encoding="UTF-8"?> <Data> <Student_ID>1234</Student_ID> <Student_ID>1267</Student_ID> <Student_ID>1890</Student_ID> <Student_ID>8743</Student_ID> <Student_ID>3226</Student_ID> <Student_ID>8123</Student_ID> </Data>
解决方案
方案1:XSLT 2.0(简洁实现)
利用XSLT 2.0内置的distinct-values()函数直接去重,代码如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <xsl:template match="/Data"> <Data> <xsl:for-each select="distinct-values(Base/Student_ID | Sub/Student_ID)"> <Student_ID><xsl:value-of select="."/></Student_ID> </xsl:for-each> </Data> </xsl:template> </xsl:stylesheet>
- 逻辑说明:匹配根节点
Data,创建新的Data元素;通过Base/Student_ID | Sub/Student_ID获取所有Student_ID节点,用distinct-values()去重后,循环生成对应的Student_ID元素。
方案2:XSLT 1.0(兼容旧版本)
XSLT 1.0没有内置去重函数,采用Muenchian分组实现去重:
<?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" indent="yes" encoding="UTF-8"/> <!-- 定义分组键:以Student_ID的文本内容为键 --> <xsl:key name="studentKey" match="Student_ID" use="text()"/> <xsl:template match="/Data"> <Data> <!-- 只输出每个分组的第一个节点(即去重后的节点) --> <xsl:copy-of select="(Base/Student_ID | Sub/Student_ID)[generate-id() = generate-id(key('studentKey', text())[1])]"/> </Data> </xsl:template> </xsl:stylesheet>
- 逻辑说明:先定义键
studentKey,以Student_ID的文本内容作为分组依据;然后筛选出每个分组里的第一个节点,实现去重,最后复制这些节点到新的Data元素中。
内容的提问来源于stack exchange,提问作者Thusara Deemantha
相关产品推荐
相关产品推荐

