You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用XSLT 1.0统计XML中不同<tag>值的监狱数量?

使用XSLT 1.0(xmlstarlet)统计XML中不同值的监狱数量

数据结构

XML文件包含数千条监狱数据,结构示例如下:

<bases xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<marker>
        <name>United States Penitentiary, Canaan</name>
        <adr>Canaan</adr>
        <state>Pennsylvania</state>
        <geo>41.562778, -75.421389</geo>
        <tag>Federal</tag>
        <wiki>United_States_Penitentiary,_Canaan</wiki>
</marker>
<marker>
        <name>Mohawk Correctional Facility</name>
        <adr>Rome</adr>
        <state>New York</state>
        <geo>43.184511, -75.483992</geo>
        <tag>State</tag>
        <wiki>Mohawk_Correctional_Facility</wiki>
</marker>
...
</bases>

需求

需要统计<tag>标签下不同值(共8种,如Federal、State)对应的监狱数量,使用XSLT 1.0处理器(xmlstarlet)。

尝试过的代码及问题

  1. 最初尝试的代码无法得到正确结果:
<xsl:template match="/bases/marker[tag='Federal']">
        TOTAL = <xsl:value-of select="count(.)"/>
</xsl:template>

问题:该模板会匹配每个符合条件的<marker>节点,每次输出的count(.)都是1,最终会输出多个1而非总数。

  1. 单个值统计的代码可行:
<xsl:template match="/">
    TOTAL = <xsl:value-of select="count(//bases/marker[tag='Federal']) "/>
</xsl:template>

但扩展到多值统计时出现错误,比如统计State时结果为0(实际有数百条数据):

<xsl:template match="/">
        Federal = <xsl:value-of select="count(//bases/marker[tag='Federal']) "/>
        State = <xsl:value-of select="count(//bases/marker[tag='Statel']) "/>
</xsl:template>

问题:这里存在笔误,把State写成了Statel;同时手动逐个枚举8种tag值不仅繁琐,后续tag值变化时还需修改代码。

解决方案

方案1:修正笔误,手动统计所有tag值

若坚持手动统计,先修正拼写错误,确保每个tag值匹配正确:

<xsl:template match="/">
        Federal = <xsl:value-of select="count(//bases/marker[tag='Federal']) "/>
        State = <xsl:value-of select="count(//bases/marker[tag='State']) "/>
        <!-- 继续添加其他6种tag值的统计行 -->
</xsl:template>

方案2:使用Muenchian分组自动统计所有不同tag值(更高效)

XSLT 1.0中可通过Muenchian分组方法,自动识别所有不同的<tag>值并统计数量,无需手动枚举:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 定义分组键:基于tag的文本值 -->
    <xsl:key name="tag-group" match="marker" use="tag"/>

    <xsl:template match="/">
        <xsl:for-each select="//bases/marker[generate-id() = generate-id(key('tag-group', tag)[1])]">
            <!-- 输出tag值和对应的数量 -->
            <xsl:value-of select="tag"/> = <xsl:value-of select="count(key('tag-group', tag))"/>
            <xsl:text>&#10;</xsl:text> <!-- 添加换行,优化输出格式 -->
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

使用xmlstarlet执行的命令

将上述XSLT保存为count-tags.xsl,执行以下命令即可得到统计结果:

xmlstarlet tr count-tags.xsl your-prison-data.xml

内容的提问来源于stack exchange,提问作者Ed S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:43:22