如何使用XSLT-3检查XML文件并生成重复元素报告
XSLT 3.0 生成XML重复元素报告方案
嘿,我帮你搞定了这个需求——用XSLT 3.0检测XML里重复的<food>元素(按<name>字段判断),还能生成可读性强的重复元素报告。先把你提供的示例XML补全为完整可运行的版本:
<breakfast_menu> <food> <name>01</name> <price>$5.95</price> <description>Two of our famous Belgian Waffles with plenty of real maple [syrup]</description> <calories>650</calories> </food> <food> <name>01</name> <price>$7.95</price> <description>Two of our famous Belgian Waffles with plenty of real maple [syrup]</description> <calories>750</calories> </food> <food> <name>02</name> <price>$4.95</price> <description>Single Belgian Waffle with maple syrup</description> <calories>400</calories> </food> </breakfast_menu>
接下来是核心的XSLT 3.0样式表,它会自动分组重复的name值,输出带样式的HTML报告:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes" encoding="UTF-8"/> <!-- 主模板:处理根节点breakfast_menu --> <xsl:template match="/breakfast_menu"> <html> <head> <title>重复Food元素报告</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } .duplicate-group { border: 1px solid #ccc; padding: 15px; margin-bottom: 20px; border-radius: 5px; } .duplicate-title { color: #d9534f; font-size: 1.2em; margin-top: 0; } .food-item { margin-left: 20px; margin-bottom: 10px; padding: 10px; background-color: #f9f9f9; border-radius: 3px; } .no-duplicates { color: #5cb85c; font-size: 1.1em; } </style> </head> <body> <h1>早餐菜单重复元素报告</h1> <!-- 筛选出所有存在重复的name分组 --> <xsl:variable name="duplicate-groups" as="element()*"> <xsl:for-each-group select="food" group-by="name"> <xsl:if test="count(current-group()) > 1"> <group name="{current-grouping-key()}"> <xsl:copy-of select="current-group()"/> </group> </xsl:if> </xsl:for-each-group> </xsl:variable> <!-- 根据是否有重复生成对应内容 --> <xsl:choose> <xsl:when test="$duplicate-groups"> <xsl:for-each select="$duplicate-groups"> <div class="duplicate-group"> <h2 class="duplicate-title">重复名称: <xsl:value-of select="@name"/></h2> <p>共找到 <xsl:value-of select="count(food)"/> 条重复记录:</p> <xsl:for-each select="food"> <div class="food-item"> <p><strong>价格:</strong> <xsl:value-of select="price"/></p> <p><strong>描述:</strong> <xsl:value-of select="description"/></p> <p><strong>热量:</strong> <xsl:value-of select="calories"/> 卡路里</p> </div> </xsl:for-each> </div> </xsl:for-each> </xsl:when> <xsl:otherwise> <p class="no-duplicates">未发现任何重复的Food元素</p> </xsl:otherwise> </xsl:choose> </body> </html> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 分组筛选:用
<xsl:for-each-group>按<name>的值分组,只保留成员数量大于1的分组(也就是有重复的name)。 - 友好输出:生成HTML格式报告,带基础CSS样式,让重复记录一目了然;如果没有重复,会显示绿色的提示信息。
- XSLT 3.0特性:用到了变量类型声明(
as="element()*")、current-group()和current-grouping-key()这些分组专用函数,都是XSLT 3.0的标准功能。
运行后输出的报告示例
执行这个样式表后,会得到如下HTML报告(浏览器打开后样式美观,结构清晰):
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>重复Food元素报告</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } .duplicate-group { border: 1px solid #ccc; padding: 15px; margin-bottom: 20px; border-radius: 5px; } .duplicate-title { color: #d9534f; font-size: 1.2em; margin-top: 0; } .food-item { margin-left: 20px; margin-bottom: 10px; padding: 10px; background-color: #f9f9f9; border-radius: 3px; } .no-duplicates { color: #5cb85c; font-size: 1.1em; } </style> </head> <body> <h1>早餐菜单重复元素报告</h1> <div class="duplicate-group"> <h2 class="duplicate-title">重复名称: 01</h2> <p>共找到 2 条重复记录:</p> <div class="food-item"> <p><strong>价格:</strong> $5.95</p> <p><strong>描述:</strong> Two of our famous Belgian Waffles with plenty of real maple [syrup]</p> <p><strong>热量:</strong> 650 卡路里</p> </div> <div class="food-item"> <p><strong>价格:</strong> $7.95</p> <p><strong>描述:</strong> Two of our famous Belgian Waffles with plenty of real maple [syrup]</p> <p><strong>热量:</strong> 750 卡路里</p> </div> </div> </body> </html>
内容的提问来源于stack exchange,提问作者Jeka Tay
相关产品推荐
相关产品推荐

