XSLT计数具有给定值的元素 [英] XSLT counting elements with a given value

查看:174
本文介绍了XSLT计数具有给定值的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要计算XML文件中具有特定值(以验证唯一性)的元素数。 XML文件如下所示:



编辑:我更新了原来的简化XML与某人设计的实际毛茸茸的混乱。不幸的是,这将使所有以前的答案混淆和错误,除非编辑。

 < root& 
< ac>
< Properties>
< Property Name =Alive>
< Properties>
< Property Name =ID>
< Properties>
< Property Name =Value>
< long> 11007< / long>
< / Property>
< / Properties>
< / Property>
< / Properties>
< / Property>
< Property Name =Dead>
< Properties>
< Property Name =ID>
< Properties>
< Property Name =Value>
< long> 11008< / long>
< / Property>
< / Properties>
< / Property>
< / Properties>
< / Property>
...
< Property Name =MostlyDeadAllDay>
< Properties>
< Property Name =ID>
< Properties>
< Property Name =Value>
< long> 99001< / long>
< / Property>
< / Properties>
< / Property>
< / Properties>
< / Property>
< / Properties>
< / ac>
< / root>

我试图定义一个变量,看看有多少属性在活动/在模板参数中定义的长值(ID)。这些行的东西(虽然我怀疑这是错误的)...

 < xsl:param name =parPropId/ > 
< xsl:variable name =countProperties>
< xsl:value -of select =count(/ root / ac /
属性/属性/
属性/属性[@Name ='ID'] /
属性/ Property [@Name ='Value'] / long = $ parPropId)/>
< / xsl:variable>

可以在ID级别定义多个Property元素。但我相当肯定我可以指望只有一个属性元素(价值)在ID下,只有一个长元素下价值。



[免责声明]设计整体XML文件的人我坚持使用REALLY不知道如何结构XML(例如,属性与元素的向后使用)。我害怕我的XSLT思维已暂时翘曲:)结果。 [/ disclaimer]

解决方案

此XPath:

  count(// Property [long ='11007'])

  count(// Property / long [text()='11007'])

...除了第一个计数 Property 条件,第二个计数个子节点。



根据您的意见并阅读您的问题a几次的时候,我相信你想找到唯一性基于组合的标准。因此,实际上,我认为你实际上是检查多个条件。

  count(// Property [@Name ='Alive'] [long ='11007' ])

,因为它的意思与以下相同:

  count(// Property [@Name ='Alive'and long ='11007'])

当然,您可以用模板中的参数替换值。



编辑 >

你是对的XML是可怕的。事实上,这是一个彻底的 CodingHorror 候选人!我不得不继续记录,以跟踪我目前在的属性节点。我感到你的痛苦!



这里:

  / root / ac / Properties / Property [Properties / Property / Properties / Property / long = $ parPropId])

请注意,我已删除所有其他检查(ID和值)。它们似乎不是必需的,因为您能够使用XML中的层次结构到达相关节点。此外,您已经提到对唯一性的检查仅基于 long 元素的内容。


I need to count the number of elements in an XML file that have a particular value (to verify uniqueness). The XML file looks like this:

EDIT: I updated the original "simplified" XML with the actual hairy mess someone designed. Unfortunately, this is going to make all the previous Answers really confusing and wrong unless edited.

<root>
  <ac>
   <Properties>
     <Property Name="Alive">
      <Properties>
        <Property Name="ID">
         <Properties>
           <Property Name="Value">
            <long>11007</long>
           </Property>
         </Properties>
        </Property>
      </Properties>
     </Property>
     <Property Name="Dead">
      <Properties>
        <Property Name="ID">
         <Properties>
           <Property Name="Value">
            <long>11008</long>
           </Property>
         </Properties>
        </Property>
      </Properties>
     </Property>
     ...
     <Property Name="MostlyDeadAllDay">
      <Properties>
        <Property Name="ID">
         <Properties>
           <Property Name="Value">
            <long>99001</long>
           </Property>
         </Properties>
        </Property>
      </Properties>
     </Property>
   </Properties>
  </ac>
</root>

I am trying to define a variable to see how many of the properties at the Alive/Dead level have the long value (ID) as defined in a template parameter. Something along these lines (though I suspect this is wrong)...

<xsl:param name="parPropId"/>
<xsl:variable name="countProperties">
   <xsl:value-of select="count(/root/ac/
      Properties/Property/
      Properties/Property[@Name = 'ID']/
      Properites/Property[@Name = 'Value']/long = $parPropId)"/>
</xsl:variable>

There can be multiple Property elements defined at the "ID" level. But I am fairly certain I can count on just one Property element ("Value") under "ID", and only one "long" element under "Value".

[disclaimer] Whoever designed the overall XML file I'm stuck working with REALLY didn't know how to structure XML (e.g., backwards use of attributes versus elements). I fear my XSLT thinking has temporarily been warped :) as a result. [/disclaimer]

解决方案

This XPath:

count(//Property[long = '11007'])

returns the same value as:

count(//Property/long[text() = '11007'])

...except that the first counts Property nodes that match the criterion and the second counts long child nodes that match the criterion.

As per your comment and reading your question a couple of times, I believe that you want to find uniqueness based on a combination of criteria. Therefore, in actuality, I think you are actually checking multiple conditions. The following would work as well:

count(//Property[@Name = 'Alive'][long = '11007'])

because it means the same thing as:

count(//Property[@Name = 'Alive' and long = '11007'])

Of course, you would substitute the values for parameters in your template. The above code only illustrates the point.

EDIT (after question edit)


You were quite right about the XML being horrible. In fact, this is a downright CodingHorror candidate! I had to keep recounting to keep track of the "Property" node I was on presently. I feel your pain!

Here you go:

count(/root/ac/Properties/Property[Properties/Property/Properties/Property/long = $parPropId])

Note that I have removed all the other checks (for ID and Value). They appear not to be required since you are able to arrive at the relevant node using the hierarchy in the XML. Also, you already mentioned that the check for uniqueness is based only on the contents of the long element.

这篇关于XSLT计数具有给定值的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆