Reputation: 1081
The XSLT and XML shown below generates the following output:
<CodeGroupA>Found</CodeGroupA>
<CodeGroupB>Not found</CodeGroupB>
<CodeGroupA>Found</CodeGroupA>
<CodeGroupB>Not found</CodeGroupB>
<CodeGroupA>Not found</CodeGroupA>
<CodeGroupB>Not found</CodeGroupB>
I need to generate this output:
<CodeGroupA>Found</CodeGroupA>
<CodeGroupB>Not found</CodeGroupB>
I attempted a number of different methods using recursion and for-each but I cannot figure it out. Any suggestion would be appreciated.
Thanks in advance.
Here is my 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>
Here is my input 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>
Upvotes: 0
Views: 1347
Reputation: 70628
You should really match on the Diagnoses
element, otherwise you will get something output for each Diagnosis
which is not really what you want.
But if you do this, you can get the result you want by doing this...
<CodeGroupA>
<xsl:value-of select="if (Diagnosis/Code=$CodeGroupA) then 'Found' else 'Not found'" />
</CodeGroupA>
And similarly for CodeGroupB
.
Of course, you could avoid repeated logic by putting the logic in a function. Try this 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>
Upvotes: 2
Reputation: 167651
Change the context node for the tests:
<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
Upvotes: 1