尝试计算某些 XML 元素的 () 数量

Trying to count() number of certain XML elements

提问人:Ed S. 提问时间:11/15/2023 最后编辑:Ed S. 更新时间:11/15/2023 访问量:44

问:

我有一个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>

我想统计<标签>为“联邦”的监狱数量。我需要生成八个值的总数。我正在使用 XSLT v1.0 处理器 (xmlstarlet),我是 count() 的新手。

我有很多 XSL 示例不起作用,我不确定这里应该包含哪些。(我已经在这里呆了几个小时了。这是一个不起作用的:

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

请帮忙。

以下是 Sebastien 解决 count() 问题的解决方案:

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

但是我有多个 <tag> 值要处理,这不起作用 - 当有数百个时,状态等于零:

<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>
XML XSLT 计数

评论

1赞 Sebastien 11/15/2023
我不确定您的模板是如何设置的,但这样做应该会给您计数: count(//bases/marker[tag='Federal'])
0赞 Ed S. 11/15/2023
谢谢你让我走上了正确的轨道。
1赞 michael.hor257k 11/15/2023
对于单个值,执行就足够了。如果要对 的不同值进行多次计数,请考虑分组 - 请参阅:stackoverflow.com/tags/xslt-grouping/infocount(/bases/marker[tag='Federal'])tag
1赞 Sebastien 11/15/2023
jenitennison.com/xslt/grouping/muenchian.html
1赞 Daniel Haley 11/15/2023
在 1.0 中分组比在 2.0+ 中分组更困难,但绝对不是不可能。我添加了一个示例作为答案。

答:

0赞 Daniel Haley 11/15/2023 #1

下面是 XSLT 1.0 中 Muenchian 分组的示例,与注释中的链接一起进行。

输入(添加了另一个以显示正确计数markerState)

<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>
    <marker>
        <name>Casa Bonita</name>
        <adr>Lakewood</adr>
        <state>CO</state>
        <geo>39.741927, -105.070828</geo>
        <tag>State</tag>
        <wiki>Casa_Bonita</wiki>
    </marker>
</bases>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:key name="marker_by_tag" match="marker" use="tag"/>
    
    <xsl:template match="/*">
        <xsl:for-each select="marker[count(.|key('marker_by_tag',tag)[1])=1]">
            <xsl:value-of select="concat(tag,' = ',count(key('marker_by_tag',tag)),'&#xA;')"/>
        </xsl:for-each>
    </xsl:template>
    
</xsl:stylesheet>

输出

Federal = 1
State = 2