Count specific children only through XPath

2019-07-14 05:17发布

I have a situation where I have to find the count of few Boolean field values only if they are true.

Input XML:

<PersonInfo>
  <ArrayOfPersonInfo>
   <CertAsAdultFlag>true</CertAsAdultFlag>
    <DeceasedFlag>true</DeceasedFlag>
    <WantedFlag>false</WantedFlag>
    <CPSORFlag>true</CPSORFlag>
    <ConditonalReleaseFlag>false</ConditonalReleaseFlag>
    <ProbationFlag>true</ProbationFlag>
    <MissingFlag>true</MissingFlag>
    <ATLFlag>true</ATLFlag>
    <CCWFlag>false</CCWFlag>
    <VictimIDTheftFlag>true</VictimIDTheftFlag>
  </ArrayOfPersonInfo>    
</PersonInfo>

I need to find the count of these flags with the condition if they are 'true'.

Here is what I tried and was unsuccessful with:

<xsl:variable name="AlertCount" select="
  count(
    PersonInfo/ArrayOfPersonInfo[
      CPSORFlag[.='true'] | CertAsAdultFlag[.='true'] | 
      DeceasedFlag[.='true'] | WantedFlag[.='true'] | 
      ConditonalReleaseFlag[.='true'] | MissingFlag[.='true'] | 
      ATLFlag[.='true'] | ProbationFlag[.='true'] | CCWFlag[.='true'] | 
      VictimIDTheftFlag[.='true'] | CHRIFlag[.='true'] | 
      CivilWritFlag[.='true'] | MentalPetitionFlag[.='true'] |
      ProtectionOrderFlag[.='true'] | juvWantedFlag[.='true'] | 
      WeaponsFlag[.='true'] | WorkCardFlag[.='true']
    ]
  )
"/> 

I really need help with this from someone as I've been trying hard to get through it. Thanks in advance.

标签: xslt xpath
1条回答
做个烂人
2楼-- · 2019-07-14 05:45
<xsl:variable name="AlertCount" select="count(PersonInfo//*[. = 'true'])" /> 

Here's why your's does not work:

The square brackets in your approach create a predicate over a node set.

That node-set was the union of all mentioned child nodes who fulfilled their condition. A non-empty node-set evaluates to true, a non-empty one to false.

In consequence your count() would always be 1 if any of the children were true and always be 0 if all of them were false.

In other words: You selected one <ArrayOfPersonInfo> node. If it fulfilled a condition (having any number of children with 'true' as their value) it was counted, otherwise not.


After clarification in the comments ("I need to worry only about the flags I mentioned in the above XML"):

<xsl:variable name="AlertCount" select="
  count(
    PersonInfo//*[
      self::CPSORFlag or
      self::CertAsAdultFlag or
      self::DeceasedFlag or
      self::WantedFlag or
      self::ConditonalReleaseFlag or
      self::MissingFlag or
      self::ATLFlag or
      self::ProbationFlag or
      self::CCWFlag or
      self::VictimIDTheftFlag or
      self::CHRIFlag or
      self::CivilWritFlag or
      self::MentalPetitionFlag or
      self::ProtectionOrderFlag or
      self::juvWantedFlag or
      self::WeaponsFlag or
      self::WorkCardFlag
    ][. = 'true']
  )
" />
查看更多
登录 后发表回答