0

我有一种情况,我想根据每个节点顶部设置的条件计算返回的标签数量。

我有近 20 个标志,如下例所示。我们不知道这些标志中有多少是真的。如果 Flag 为 TRUE,则将返回自定义文本。我想知道返回的标志数。我尝试了很多使用变量的方法,但都没有成功。

<!--CPSOR ALERT FLAG-->
<xsl:if test="Person/PersonInfo/CPSORFlag ='true'">                    
  <scope:PersonAlert>
    <!--PersonAlerts.PersonAlertText-->
    <scope:AlertText>                        
      <xsl:text>CONV PER/SOFF</xsl:text>
    </scope:AlertText>
  </scope:PersonAlert>
</xsl:if>
<!--CERTASADULT ALERT FLAG-->
<xsl:if test="Person/PersonInfo/CertAsAdultFlag ='true'">
   <scope:PersonAlert>
    <!--PersonAlerts.PersonAlertText-->
    <scope:AlertText>
      <xsl:text>CERT ADULT</xsl:text>
    </scope:AlertText>
  </scope:PersonAlert>
</xsl:if>
<!--DECEASED ALERT FLAG-->
<xsl:if test="Person/PersonInfo/DeceasedFlag ='true'">
  <scope:PersonAlert>
    <!--PersonAlerts.PersonAlertText-->
    <scope:AlertText>
      <xsl:text>DECEASED</xsl:text>
    </scope:AlertText>
  </scope:PersonAlert>
</xsl:if>

这是示例 XML

在此处输入图像描述

4

2 回答 2

1

一般问题的经典示例:您想从相同的输入数据计算两个不同的结果。有几种方法。

(a) 咬紧牙关,对输入进行两次处理。这是 james31rock 选择的 solytion。

(b) 与 (a) 相同,但尝试识别您多次计算的表达式,并将这些表达式的结果放入变量中,以避免重复计算。

(c) 将第一次计算的结果放入一个变量中,对该变量的结果进行第二次计算。

我想我会倾向于按照(b)的方式做一些事情。这是 XSLT 2.0 - 如果你付给我很多钱,我只做 XSLT 1.0。另外,我假设Person/PersonInfo/CPSORFlag每个表达式都选择一个节点。

<xsl:variable name="flags" select="Person/PersonInfo/(CPSORFlag, CertAsAdultFlag, DeceasedFlag, ....)"/>

<xsl:variable name="count" select="count($flags[.='true'])"/>

<xsl:apply-templates select="$flags[. = 'true']"/>

然后

<xsl:template match="Person/PersonInfo/*" priority="5">
   <scope:PersonAlert>
    <!--PersonAlerts.PersonAlertText-->
    <scope:AlertText>
      <xsl:next-match/>
    </scope:AlertText>
  </scope:PersonAlert>
</xsl:template>

<xsl:template match="CPSORFlag" priority="4">CONV PER/SOFF</xsl:template>
<xsl:template match="CertAsAdultFlag" priority="4">CERT ADULT</xsl:template>
<xsl:template match="DeceasedFlag" priority="4">DECEASED</xsl:template>

etc
于 2012-07-30T22:39:39.763 回答
0

假设您的 XML 是这样的:

<root>
  <Person>
    <PersonInfo>
      <CPSORFlag>true</CPSORFlag>
    </PersonInfo>
  </Person>
  <Person>
    <PersonInfo>
      <ConditonalReleaseFlag>true</ConditonalReleaseFlag>
    </PersonInfo>
  </Person>
  <Person>
    <PersonInfo>
      <MissingFlag>true</MissingFlag>
    </PersonInfo>
  </Person>
</root>

使用 count() 函数

<NumberOfFlags>
<xsl:value-of select="count(//Person/PersonInfo[CPSORFlag[.='true'] or CPSORFlag[.='true']])"/>
</NumberOfFlags>

或者

<NumberOfFlags>
<xsl:value-of select="count(//Person/PersonInfo[CPSORFlag='true' or CPSORFlag='true'])"/>
</NumberOfFlags>

在上面显示的过滤器中添加所有不同类型的标志

[CPSORFlag='true' 或等...]

这是一个经过验证的示例

标志数量

编辑

鉴于您新粘贴的 XML,此模板应该可以解决问题

XML

 <Person>
    <PersonInfo>
      <CPSORFlag>true</CPSORFlag>
       <MissingFlag>true</MissingFlag>
       <ConditonalReleaseFlag>true</ConditonalReleaseFlag>
    </PersonInfo>
  </Person>

样式表

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:java="http://xml.apache.org/xslt/java" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="java" version="1.0">
  <xsl:output media-type="text/xml" method="xml"/>
  <!-- Filters refdoc based on condition and  data  -->
  <xsl:template match="/">
    <xsl:apply-templates select="//PersonInfo"/>
  </xsl:template>

  <xsl:template match="PersonInfo">
    <NumberOfFlags>
         <xsl:value-of select="count(CPSORFlag[.='true']|MissingFlag[.='true']|ConditonalReleaseFlag[.='true'])"/>
     </NumberOfFlags>
  </xsl:template>
</xsl:stylesheet>

只需要使用 | 添加一个新标志 计数函数内的符号

CPSORFlag[.='true'] | MissingFlag[.='true']

于 2012-07-30T19:58:53.677 回答