XSLT 2.0:如何确定列表中是否存在至少一个值?

时间:2018-06-28 21:05:33

标签: xslt xslt-2.0

下面显示的XSLT和XML生成以下输出:

<CodeGroupA>Found</CodeGroupA>
<CodeGroupB>Not found</CodeGroupB>
<CodeGroupA>Found</CodeGroupA>
<CodeGroupB>Not found</CodeGroupB>
<CodeGroupA>Not found</CodeGroupA>
<CodeGroupB>Not found</CodeGroupB>

我需要生成以下输出:

<CodeGroupA>Found</CodeGroupA>
<CodeGroupB>Not found</CodeGroupB>

我尝试了使用递归和for-each的多种方法,但是我无法弄清楚。任何建议将不胜感激。

谢谢。

这是我的XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:math="http://www.w3.org/2005/xpath-functions/math"
  xmlns:map="http://www.w3.org/2005/xpath-functions/map"
  xmlns:array="http://www.w3.org/2005/xpath-functions/array"
  exclude-result-prefixes="xs math map array"
  version="3.0">

  <!-- input/output configuration -->
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:variable name="CodeGroupA" select="'12', '13'" />
  <xsl:variable name="CodeGroupB" select="'17', '18'" />

  <xsl:template match="/Diagnoses/Diagnosis" >

    <xsl:if test=".[Code=($CodeGroupA)]">
        <CodeGroupA>Found</CodeGroupA>
    </xsl:if>

    <xsl:if test="not(.[Code=($CodeGroupA)])">
        <CodeGroupA>Not found</CodeGroupA>
    </xsl:if>

    <xsl:if test=".[Code=($CodeGroupB)]">
        <CodeGroupB>Found</CodeGroupB>
    </xsl:if>

    <xsl:if test="not(.[Code=($CodeGroupB)])">
        <CodeGroupB>Not found</CodeGroupB>
    </xsl:if>
  </xsl:template>

  <xsl:template match="text()|@*">
  </xsl:template>

</xsl:stylesheet>

这是我的输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<Diagnoses>
  <Diagnosis>
    <Code>12</Code>
  </Diagnosis>
  <Diagnosis>
    <Code>13</Code>
  </Diagnosis>
  <Diagnosis>
    <Code>14</Code>
  </Diagnosis>
</Diagnoses>

2 个答案:

答案 0 :(得分:2)

您应该在Diagnoses元素上真正匹配,否则,每个Diagnosis都会得到输出,这并不是您真正想要的。

但是,如果执行此操作,则可以通过此操作获得所需的结果...

<CodeGroupA>
    <xsl:value-of select="if (Diagnosis/Code=$CodeGroupA) then 'Found' else 'Not found'" />
</CodeGroupA>

CodeGroupB也是如此。

当然,您可以通过将逻辑放入函数中来避免重复的逻辑。试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:my="my" version="3.0">

  <!-- input/output configuration -->
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:variable name="CodeGroupA" select="'12', '13'" />
  <xsl:variable name="CodeGroupB" select="'17', '18'" />

  <xsl:template match="/Diagnoses" >

    <CodeGroupA>
        <xsl:value-of select="my:check(Diagnosis/Code, $CodeGroupA)" />
    </CodeGroupA>

    <CodeGroupB>
        <xsl:value-of select="my:check(Diagnosis/Code, $CodeGroupB)" />
    </CodeGroupB>
  </xsl:template>

  <xsl:function name="my:check">
      <xsl:param name="nodes" />
      <xsl:param name="group" />
      <xsl:value-of select="if ($nodes = $group) then 'Found' else 'Not found'" />
  </xsl:function>
</xsl:stylesheet>

答案 1 :(得分:1)

更改测试的上下文节点:

  <xsl:template match="/Diagnoses" >

    <xsl:if test="Diagnosis/Code = $CodeGroupA">
        <CodeGroupA>Found</CodeGroupA>
    </xsl:if>

    <xsl:if test="not(Diagnosis/Code = $CodeGroupA)">
        <CodeGroupA>Not found</CodeGroupA>
    </xsl:if>

    <xsl:if test="Diagnosis/Code = $CodeGroupB">
        <CodeGroupB>Found</CodeGroupB>
    </xsl:if>

    <xsl:if test="not(Diagnosis/Code = $CodeGroupB)">
        <CodeGroupB>Not found</CodeGroupB>
    </xsl:if>
  </xsl:template>

https://xsltfiddle.liberty-development.net/bdxtq9