Reputation: 1081
I have the following Input, Transform and Output XML. The Output XML is not what I am expecting. I am attempting to use the mode attribute in my templates to separate my processing into two steps. Step1 filters the Input XML and Step2 processes specific nodes in what I am hoping is the filtered Input XML. My Step2 templates simply output what they receive so I am expecting to see the full description of the nodes selected for each template. The Output XML contains only the top-level node labels (Patient,Encounters,Diagnoses) and only the text of the node itself.
I have the following XSLT fiddle at My XSLT fiddle that shows my issue, I hope clearly.
Input XML
<?xml version="1.0" encoding="utf-8" ?>
<root>
<Container>
<Patient>
<BirthTime>2001-01-01T00:00:00Z</BirthTime>
</Patient>
<Encounters>
<Encounter>
<EncounterNumber>1</EncounterNumber>
<FromTime>2021-04-01T00:00:00Z</FromTime>
</Encounter>
<Encounter>
<EncounterNumber>2</EncounterNumber>
<FromTime>2021-03-01T00:00:00Z</FromTime>
</Encounter>
</Encounters>
<Diagnoses>
<Diagnosis>
<EncounterNumber>1</EncounterNumber>
</Diagnosis>
<Diagnosis>
<EncounterNumber>2</EncounterNumber>
</Diagnosis>
</Diagnoses>
</Container>
</root>
Transform XML
<?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="#all"
version="3.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="encounterNumbers">
<EncounterNumber>2</EncounterNumber>
</xsl:variable>
<!-- START PROCESSING -->
<xsl:template match="node()|@*">
<xsl:apply-templates select="." mode="step1"/>
</xsl:template>
<!-- STEP1 TEMPLATES -->
<xsl:template name="filterSDA" mode="step1" match="node()|@*">
<xsl:variable name="filteredSDA">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:variable>
<xsl:apply-templates select="$filteredSDA" mode="step2"/>
</xsl:template>
<xsl:template match="//Encounters/Encounter[not(EncounterNumber = $encounterNumbers/EncounterNumber)]" mode="step1"/>
<xsl:template match="//Diagnoses/Diagnosis[not(EncounterNumber = $encounterNumbers/EncounterNumber)]" mode="step1"/>
<!-- STEP2 TEMPLATES -->
<xsl:template name="demographics" mode="step2" match="Patient">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template name="clinical" mode="step2" match="Encounters|Diagnoses">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
Output XML
<?xml version="1.0" encoding="UTF-8"?>
<Patient>
2001-01-01T00:00:00Z
</Patient>
<Encounters>
2
2021-03-01T00:00:00Z
</Encounters>
<Diagnoses>
2
</Diagnoses>
Upvotes: 0
Views: 45
Reputation: 167696
I think you are overcomplicating things by mixing named templates (which you seem to call nowhere) with matching templates.
Furthermore, if you want a two phase processing with two different modes, I would do that at the top level, pushing the result of processing the whole input through the first mode into a variable and then applying the second mode on that variable:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="encounterNumbers">
<EncounterNumber>2</EncounterNumber>
<EncounterNumber>3</EncounterNumber>
<EncounterNumber>4</EncounterNumber>
</xsl:variable>
<xsl:mode name="step1" on-no-match="shallow-copy"/>
<xsl:mode name="step2" on-no-match="shallow-copy"/>
<!-- START PROCESSING -->
<xsl:template match="/">
<xsl:variable name="step-1-result">
<xsl:apply-templates mode="step1"/>
</xsl:variable>
<xsl:apply-templates select="$step-1-result/node()" mode="step2"/>
</xsl:template>
<!-- mode step1 templates -->
<xsl:template match="//Encounters/Encounter[not(EncounterNumber = $encounterNumbers/EncounterNumber)]" mode="step1"/>
<xsl:template match="//Diagnoses/Diagnosis[not(EncounterNumber = $encounterNumbers/EncounterNumber)]" mode="step1"/>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/asoTKZ/20
Upvotes: 1