XSLT计算具有给定值的元素

时间:2009-04-06 15:24:35

标签: xslt count elements

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

编辑:我更新了原始的“简化”XML,其中包含了某人设计的实际毛茸茸的混乱。不幸的是,除非经过编辑,否则这将使以前的所有Answers真正令人困惑和错误。

<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>

我正在尝试定义一个变量,以查看Alive / Dead级别有多少属性具有模板参数中定义的长值(ID)。沿着这些方向的东西(虽然我怀疑这是错的)......

<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>

可以在“ID”级别定义多个Property元素。但我相当确定我可以指望“ID”下只有一个Property元素(“Value”),而“Value”下只有一个“long”元素。

[免责声明]无论是谁设计了整个XML文件我都坚持使用REALLY不知道如何构建XML(例如,向后使用属性与元素)。我担心我的XSLT思维会暂时被扭曲:)结果。 [/放弃]

3 个答案:

答案 0 :(得分:39)

这个XPath:

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

返回与:

相同的值
count(//Property/long[text() = '11007'])

...除了第一个计算符合标准的Property个节点,第二个计算符合该标准的long个子节点。

根据您的评论并多次阅读您的问题,我相信您希望根据标准组合找到唯一性。因此,实际上,我认为你实际上正在检查多个条件。以下也适用:

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

因为它意味着同样的事情:

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

当然,您可以替换模板中参数的值。上面的代码只说明了这一点。

编辑(问题编辑后)


你对XML太可怕了。事实上,这是一个彻头彻尾的CodingHorror候选人!我不得不继续叙述我现在所处的“属性”节点。我感觉到你的痛苦!

你走了:

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

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

答案 1 :(得分:2)

你的xpath有点偏离:

count(//Property/long[text()=$parPropId])

编辑:Cerebrus非常正确地指出OP中的代码(使用节点的隐含值)绝对适合您的目的。事实上,因为你很可能想要使用“Property”节点而不是“long”节点,所以要求//Property[long=$parPropId]可能 superior 而不是text()xpath,虽然你可以在可读性方面为后者辩护。

我能说什么,今天我有点累了。)

答案 2 :(得分:-2)

<xsl:variable name="count" select="count(/Property/long = $parPropId)"/>

未经测试但我认为应该有效。我假设属性节点是根节点的直接子节点,因此取出后代选择器以实现性能