source: qrda/schematron/schema_compiled.xsl@ 906

Last change on this file since 906 was 906, checked in by George Lilly, 14 years ago

initial QRDA schematron checking

File size: 32.7 KB
Line 
1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3 xmlns:xs="http://www.w3.org/2001/XMLSchema"
4 xmlns:schold="http://www.ascc.net/xml/schematron"
5 xmlns:iso="http://purl.oclc.org/dsdl/schematron"
6 xmlns:xhtml="http://www.w3.org/1999/xhtml"
7 xmlns:cda="urn:hl7-org:v3"
8 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9 version="1.0"><!--Implementers: please note that overriding process-prolog or process-root is
10 the preferred method for meta-stylesheets to use where possible. -->
11<xsl:param name="archiveDirParameter"/>
12 <xsl:param name="archiveNameParameter"/>
13 <xsl:param name="fileNameParameter"/>
14 <xsl:param name="fileDirParameter"/>
15 <xsl:variable name="document-uri">
16 <xsl:value-of select="document-uri(/)"/>
17 </xsl:variable>
18
19 <!--PHASES-->
20
21
22<!--PROLOG-->
23<xsl:output method="text"/>
24
25 <!--XSD TYPES FOR XSLT2-->
26
27
28<!--KEYS AND FUNCTIONS-->
29
30
31<!--DEFAULT RULES-->
32
33
34<!--MODE: SCHEMATRON-SELECT-FULL-PATH-->
35<!--This mode can be used to generate an ugly though full XPath for locators-->
36<xsl:template match="*" mode="schematron-select-full-path">
37 <xsl:apply-templates select="." mode="schematron-get-full-path"/>
38 </xsl:template>
39
40 <!--MODE: SCHEMATRON-FULL-PATH-->
41<!--This mode can be used to generate an ugly though full XPath for locators-->
42<xsl:template match="*" mode="schematron-get-full-path">
43 <xsl:apply-templates select="parent::*" mode="schematron-get-full-path"/>
44 <xsl:text>/</xsl:text>
45 <xsl:choose>
46 <xsl:when test="namespace-uri()=''">
47 <xsl:value-of select="name()"/>
48 <xsl:variable name="p_1" select="1+ count(preceding-sibling::*[name()=name(current())])"/>
49 <xsl:if test="$p_1&gt;1 or following-sibling::*[name()=name(current())]">[<xsl:value-of select="$p_1"/>]</xsl:if>
50 </xsl:when>
51 <xsl:otherwise>
52 <xsl:text>*[local-name()='</xsl:text>
53 <xsl:value-of select="local-name()"/>
54 <xsl:text>']</xsl:text>
55 <xsl:variable name="p_2"
56 select="1+ count(preceding-sibling::*[local-name()=local-name(current())])"/>
57 <xsl:if test="$p_2&gt;1 or following-sibling::*[local-name()=local-name(current())]">[<xsl:value-of select="$p_2"/>]</xsl:if>
58 </xsl:otherwise>
59 </xsl:choose>
60 </xsl:template>
61 <xsl:template match="@*" mode="schematron-get-full-path">
62 <xsl:text>/</xsl:text>
63 <xsl:choose>
64 <xsl:when test="namespace-uri()=''">@<xsl:value-of select="name()"/>
65 </xsl:when>
66 <xsl:otherwise>
67 <xsl:text>@*[local-name()='</xsl:text>
68 <xsl:value-of select="local-name()"/>
69 <xsl:text>' and namespace-uri()='</xsl:text>
70 <xsl:value-of select="namespace-uri()"/>
71 <xsl:text>']</xsl:text>
72 </xsl:otherwise>
73 </xsl:choose>
74 </xsl:template>
75
76 <!--MODE: SCHEMATRON-FULL-PATH-2-->
77<!--This mode can be used to generate prefixed XPath for humans-->
78<xsl:template match="node() | @*" mode="schematron-get-full-path-2">
79 <xsl:for-each select="ancestor-or-self::*">
80 <xsl:text>/</xsl:text>
81 <xsl:value-of select="name(.)"/>
82 <xsl:if test="preceding-sibling::*[name(.)=name(current())]">
83 <xsl:text>[</xsl:text>
84 <xsl:value-of select="count(preceding-sibling::*[name(.)=name(current())])+1"/>
85 <xsl:text>]</xsl:text>
86 </xsl:if>
87 </xsl:for-each>
88 <xsl:if test="not(self::*)">
89 <xsl:text/>/@<xsl:value-of select="name(.)"/>
90 </xsl:if>
91 </xsl:template>
92 <!--MODE: SCHEMATRON-FULL-PATH-3-->
93<!--This mode can be used to generate prefixed XPath for humans
94 (Top-level element has index)-->
95<xsl:template match="node() | @*" mode="schematron-get-full-path-3">
96 <xsl:for-each select="ancestor-or-self::*">
97 <xsl:text>/</xsl:text>
98 <xsl:value-of select="name(.)"/>
99 <xsl:if test="parent::*">
100 <xsl:text>[</xsl:text>
101 <xsl:value-of select="count(preceding-sibling::*[name(.)=name(current())])+1"/>
102 <xsl:text>]</xsl:text>
103 </xsl:if>
104 </xsl:for-each>
105 <xsl:if test="not(self::*)">
106 <xsl:text/>/@<xsl:value-of select="name(.)"/>
107 </xsl:if>
108 </xsl:template>
109
110 <!--MODE: GENERATE-ID-FROM-PATH -->
111<xsl:template match="/" mode="generate-id-from-path"/>
112 <xsl:template match="text()" mode="generate-id-from-path">
113 <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
114 <xsl:value-of select="concat('.text-', 1+count(preceding-sibling::text()), '-')"/>
115 </xsl:template>
116 <xsl:template match="comment()" mode="generate-id-from-path">
117 <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
118 <xsl:value-of select="concat('.comment-', 1+count(preceding-sibling::comment()), '-')"/>
119 </xsl:template>
120 <xsl:template match="processing-instruction()" mode="generate-id-from-path">
121 <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
122 <xsl:value-of select="concat('.processing-instruction-', 1+count(preceding-sibling::processing-instruction()), '-')"/>
123 </xsl:template>
124 <xsl:template match="@*" mode="generate-id-from-path">
125 <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
126 <xsl:value-of select="concat('.@', name())"/>
127 </xsl:template>
128 <xsl:template match="*" mode="generate-id-from-path" priority="-0.5">
129 <xsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
130 <xsl:text>.</xsl:text>
131 <xsl:value-of select="concat('.',name(),'-',1+count(preceding-sibling::*[name()=name(current())]),'-')"/>
132 </xsl:template>
133
134 <!--MODE: GENERATE-ID-2 -->
135<xsl:template match="/" mode="generate-id-2">U</xsl:template>
136 <xsl:template match="*" mode="generate-id-2" priority="2">
137 <xsl:text>U</xsl:text>
138 <xsl:number level="multiple" count="*"/>
139 </xsl:template>
140 <xsl:template match="node()" mode="generate-id-2">
141 <xsl:text>U.</xsl:text>
142 <xsl:number level="multiple" count="*"/>
143 <xsl:text>n</xsl:text>
144 <xsl:number count="node()"/>
145 </xsl:template>
146 <xsl:template match="@*" mode="generate-id-2">
147 <xsl:text>U.</xsl:text>
148 <xsl:number level="multiple" count="*"/>
149 <xsl:text>_</xsl:text>
150 <xsl:value-of select="string-length(local-name(.))"/>
151 <xsl:text>_</xsl:text>
152 <xsl:value-of select="translate(name(),':','.')"/>
153 </xsl:template>
154 <!--Strip characters--><xsl:template match="text()" priority="-1"/>
155
156 <!--SCHEMA SETUP-->
157<xsl:template match="/">
158 <xsl:apply-templates select="/" mode="M6"/>
159 <xsl:apply-templates select="/" mode="M7"/>
160 <xsl:apply-templates select="/" mode="M8"/>
161 </xsl:template>
162
163 <!--SCHEMATRON PATTERNS-->
164
165
166<!--PATTERN p-2.16.840.1.113883.10.20.12-errorsHL7 QRDA Category I Header (Section 2) - errors validation phase-->
167
168
169 <!--RULE -->
170<xsl:template match="/" priority="1006" mode="M6">
171
172 <!--ASSERT -->
173<xsl:choose>
174 <xsl:when test=".//cda:templateId/@root=&#34;2.16.840.1.113883.10.20.12&#34;"/>
175 <xsl:otherwise>
176 <xsl:message>
177 Error: CONF-QRDA-I-5: The value of one ClinicalDocument/templateId/@root SHALL be
178 2.16.840.1.113883.10.20.12 representing conformance to the generic
179 QRDA Category I framework constraints.
180 (.//cda:templateId/@root="2.16.840.1.113883.10.20.12")</xsl:message>
181 </xsl:otherwise>
182 </xsl:choose>
183 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M6"/>
184 </xsl:template>
185
186 <!--RULE -->
187<xsl:template match="*[cda:templateId/@root=&#34;2.16.840.1.113883.10.20.12&#34;]" priority="1005"
188 mode="M6">
189
190 <!--ASSERT -->
191<xsl:choose>
192 <xsl:when test="cda:realmCode[@code = &#34;US&#34;]"/>
193 <xsl:otherwise>
194 <xsl:message>
195 Error: CONF-QRDA-I-2: The realmCode element SHALL be present where the value of @code is US.
196 (cda:realmCode[@code = "US"])</xsl:message>
197 </xsl:otherwise>
198 </xsl:choose>
199
200 <!--ASSERT -->
201<xsl:choose>
202 <xsl:when test="cda:typeId[@root = &#34;2.16.840.1.113883.1.3&#34; and @extension = &#34;POCD_HD000040&#34;]"/>
203 <xsl:otherwise>
204 <xsl:message>
205 Error: CONF-QRDA-I-3: The value of typeId/@root SHALL be 2.16.840.1.113883.1.3 and value of
206 typeId/@extension SHALL be POCD_HD000040.
207 (cda:typeId[@root = "2.16.840.1.113883.1.3" and @extension = "POCD_HD000040"])</xsl:message>
208 </xsl:otherwise>
209 </xsl:choose>
210
211 <!--ASSERT -->
212<xsl:choose>
213 <xsl:when test="count(cda:code) = 1 and cda:code[@code=&#34;55182-0&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]"/>
214 <xsl:otherwise>
215 <xsl:message>
216 Error: CONF-QRDA-I-6: A QRDA Category I report SHALL contain exactly one
217 ClinicalDocument/code with a value of 55182-0 2.16.840.1.113883.6.1
218 LOINC STATIC.
219 (count(cda:code) = 1 and cda:code[@code="55182-0" and @codeSystem="2.16.840.1.113883.6.1"])</xsl:message>
220 </xsl:otherwise>
221 </xsl:choose>
222
223 <!--ASSERT -->
224<xsl:choose>
225 <xsl:when test="contains(translate(cda:title,'QWERTYUIOPASDFGHJKLZXCVBNM','qwertyuiopasdfghjklzxcvbnm'),'qrda incidence report') or contains(translate(cda:title,'QWERTYUIOPASDFGHJKLZXCVBNM','qwertyuiopasdfghjklzxcvbnm'),'quality measure report')"/>
226 <xsl:otherwise>
227 <xsl:message>
228 Error: CONF-QRDA-I-7: A QRDA Category I report SHALL contain exactly one
229 ClinicalDocument/title element valued with a case-insensitive, text
230 string containing "QRDA Incidence Report" or "Quality measure
231 Report".
232 (contains(translate(cda:title,'QWERTYUIOPASDFGHJKLZXCVBNM','qwertyuiopasdfghjklzxcvbnm'),'qrda incidence report') or contains(translate(cda:title,'QWERTYUIOPASDFGHJKLZXCVBNM','qwertyuiopasdfghjklzxcvbnm'),'quality measure report'))</xsl:message>
233 </xsl:otherwise>
234 </xsl:choose>
235
236 <!--ASSERT -->
237<xsl:choose>
238 <xsl:when test="count(cda:recordTarget/cda:patientRole) = 1"/>
239 <xsl:otherwise>
240 <xsl:message>
241 Error: CONF-QRDA-I-8: A QRDA Category I report SHALL contain exactly one
242 ClinicalDocument/recordTarget/PatientRole.
243 (count(cda:recordTarget/cda:patientRole) = 1)</xsl:message>
244 </xsl:otherwise>
245 </xsl:choose>
246
247 <!--ASSERT -->
248<xsl:choose>
249 <xsl:when test="cda:author/cda:assignedAuthor/cda:assignedPerson or cda:author/cda:assignedAuthor/cda:assignedAuthoringDevice "/>
250 <xsl:otherwise>
251 <xsl:message>
252 Error: CONF-QRDA-I-9: A QRDA Category I report SHALL contain one or more
253 ClinicalDocument/author/assignedAuthor/assignedPerson and/or
254 ClinicalDocument/author/assignedAuthor/assignedAuthoringDevice.
255 (cda:author/cda:assignedAuthor/cda:assignedPerson or cda:author/cda:assignedAuthor/cda:assignedAuthoringDevice)</xsl:message>
256 </xsl:otherwise>
257 </xsl:choose>
258
259 <!--ASSERT -->
260<xsl:choose>
261 <xsl:when test="count(cda:informant) = 1"/>
262 <xsl:otherwise>
263 <xsl:message>
264 Error: CONF-QRDA-I-10: A QRDA Category I report SHALL contain exactly one
265 ClinicalDocument/informant, which represents the reporting facility.
266 CONF-QRDA-I-11: An organization source of information SHALL be represented with
267 informant.
268 (count(cda:informant) = 1)</xsl:message>
269 </xsl:otherwise>
270 </xsl:choose>
271
272 <!--ASSERT -->
273<xsl:choose>
274 <xsl:when test="cda:custodian/cda:assignedCustodian/cda:representedCustodianOrganization/cda:id/@root or cda:custodian/cda:assignedCustodian/cda:representedCustodianOrganization/cda:id[@nullFlavor=&#34;MSK&#34;]"/>
275 <xsl:otherwise>
276 <xsl:message>
277 Error: CONF-QRDA-I-12: A QRDA Category I report SHALL contain exactly one
278 custodian/assignedCustodian/representedCustodianOrganization/
279 id element.
280 CONF-QRDA-I-13: The value of custodian/assignedCustodian/
281 representedCustodianOrganization/id element @root SHALL be the id
282 root of the custodian organization.
283 (cda:custodian/cda:assignedCustodian/cda:representedCustodianOrganization/cda:id/@root or cda:custodian/cda:assignedCustodian/cda:representedCustodianOrganization/cda:id[@nullFlavor="MSK"])</xsl:message>
284 </xsl:otherwise>
285 </xsl:choose>
286
287 <!--ASSERT -->
288<xsl:choose>
289 <xsl:when test="not(cda:legalAuthenticator) or count(cda:legalAuthenticator/cda:time) = 1"/>
290 <xsl:otherwise>
291 <xsl:message>
292 Error: CONF-QRDA-I-15: If present, a QRDA Category I report legalAuthenticator SHALL
293 contain exactly one ClinicalDocument/legalAuthenticator/time element.
294 (not(cda:legalAuthenticator) or count(cda:legalAuthenticator/cda:time) = 1)</xsl:message>
295 </xsl:otherwise>
296 </xsl:choose>
297
298 <!--ASSERT -->
299<xsl:choose>
300 <xsl:when test="not(cda:legalAuthenticator) or count(cda:legalAuthenticator/cda:signatureCode) = 1"/>
301 <xsl:otherwise>
302 <xsl:message>
303 Error: CONF-QRDA-I-16: If present, a QRDA Category I report legalAuthenticator SHALL
304 contain exactly one signatureCode element.
305 (not(cda:legalAuthenticator) or count(cda:legalAuthenticator/cda:signatureCode) = 1)</xsl:message>
306 </xsl:otherwise>
307 </xsl:choose>
308
309 <!--ASSERT -->
310<xsl:choose>
311 <xsl:when test="not(cda:legalAuthenticator) or cda:legalAuthenticator/cda:signatureCode[@code=&#34;S&#34;] or cda:legalAuthenticator/cda:signatureCode[@nullFlavor=&#34;MSK&#34;]"/>
312 <xsl:otherwise>
313 <xsl:message>
314 Error: CONF-QRDA-I-17: The value of a QRDA ClinicalDocument/signatureCode/@code
315 SHALL be S.
316 (not(cda:legalAuthenticator) or cda:legalAuthenticator/cda:signatureCode[@code="S"] or cda:legalAuthenticator/cda:signatureCode[@nullFlavor="MSK"])</xsl:message>
317 </xsl:otherwise>
318 </xsl:choose>
319
320 <!--ASSERT -->
321<xsl:choose>
322 <xsl:when test="not(cda:legalAuthenticator) or cda:legalAuthenticator/cda:assignedEntity"/>
323 <xsl:otherwise>
324 <xsl:message>
325 Error: CONF-QRDA-I-18: If present, a QRDA Category I report legalAuthenticator SHALL
326 contain exactly one assignedEntity element that represents the legal
327 authenticator of the document.
328 (not(cda:legalAuthenticator) or cda:legalAuthenticator/cda:assignedEntity)</xsl:message>
329 </xsl:otherwise>
330 </xsl:choose>
331
332 <!--ASSERT -->
333<xsl:choose>
334 <xsl:when test="not(cda:legalAuthenticator) or cda:legalAuthenticator/cda:assignedEntity/cda:id"/>
335 <xsl:otherwise>
336 <xsl:message>
337 Error: CONF-QRDA-I-19: The ClinicalDocument/legalAuthenticator/assigned entity
338 SHALL contain an id element.
339 (not(cda:legalAuthenticator) or cda:legalAuthenticator/cda:assignedEntity/cda:id)</xsl:message>
340 </xsl:otherwise>
341 </xsl:choose>
342
343 <!--ASSERT -->
344<xsl:choose>
345 <xsl:when test="cda:component/cda:structuredBody"/>
346 <xsl:otherwise>
347 <xsl:message>
348 Error: CONF-QRDA-I-20: A QRDA Category I report SHALL contain exactly one
349 ClinicalDocument/component/structuredBody.
350 (cda:component/cda:structuredBody)</xsl:message>
351 </xsl:otherwise>
352 </xsl:choose>
353
354 <!--ASSERT -->
355<xsl:choose>
356 <xsl:when test="count(.//cda:section/cda:code[@code=&#34;55186-1&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]) &gt; 0"/>
357 <xsl:otherwise>
358 <xsl:message>
359 Error: CONF-QRDA-I-21: A QRDA Category I report SHALL contain at least one and MAY contain
360 more than one Measure section each containing information about a single measure.
361 (count(.//cda:section/cda:code[@code="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]) &gt; 0)</xsl:message>
362 </xsl:otherwise>
363 </xsl:choose>
364 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M6"/>
365 </xsl:template>
366
367 <!--RULE -->
368<xsl:template match="*[cda:code[@code=&#34;55186-1&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]"
369 priority="1004"
370 mode="M6">
371
372 <!--ASSERT -->
373<xsl:choose>
374 <xsl:when test="self::cda:section[parent::cda:component[parent::cda:structuredBody[parent::cda:component[parent::cda:ClinicalDocument]]]] or parent::cda:section[@code=&#34;55185-3&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]/cda:component"/>
375 <xsl:otherwise>
376 <xsl:message>
377 Error: CONF-QRDA-I-22: The Measure section SHALL be a top-level section if it is not part of a
378 measure set.
379 (self::cda:section[parent::cda:component[parent::cda:structuredBody[parent::cda:component[parent::cda:ClinicalDocument]]]] or parent::cda:section[@code="55185-3" and @codeSystem="2.16.840.1.113883.6.1"]/cda:component)</xsl:message>
380 </xsl:otherwise>
381 </xsl:choose>
382
383 <!--ASSERT -->
384<xsl:choose>
385 <xsl:when test="cda:templateId"/>
386 <xsl:otherwise>
387 <xsl:message>
388 Error: CONF-QRDA-I-33: The Measure section SHALL contain at least one templateId uniquely
389 identifying each Measure name and version
390 (cda:templateId)</xsl:message>
391 </xsl:otherwise>
392 </xsl:choose>
393
394 <!--ASSERT -->
395<xsl:choose>
396 <xsl:when test="not(parent::cda:section[@code=&#34;55185-3&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]/cda:entry) or contains(translate(cda:title,&#34;QWERTYUIOPASDFGHJKLZXCVBNM&#34;,&#34;qwertyuiopasdfghjklzxcvbnm&#34;),&#34;measure section: &#34;)"/>
397 <xsl:otherwise>
398 <xsl:message>
399 Error: CONF-QRDA-I-36: A non-nested Measure section SHALL be valued with section/title
400 with a case-insensitive, text string containing "measure section:
401 &lt;measure name&gt;".
402 (not(parent::cda:section[@code="55185-3" and @codeSystem="2.16.840.1.113883.6.1"]/cda:entry) or contains(translate(cda:title,"QWERTYUIOPASDFGHJKLZXCVBNM","qwertyuiopasdfghjklzxcvbnm"),"measure section: "))</xsl:message>
403 </xsl:otherwise>
404 </xsl:choose>
405
406 <!--ASSERT -->
407<xsl:choose>
408 <xsl:when test="not(parent::cda:ClinicalDocument/cda:component/cda:structuredBody/cda:component/cda:section) or contains(translate(cda:title,&#34;QWERTYUIOPASDFGHJKLZXCVBNM&#34;,&#34;qwertyuiopasdfghjklzxcvbnm&#34;),&#34;measure section&#34;)"/>
409 <xsl:otherwise>
410 <xsl:message>
411 Error: CONF-QRDA-I-37: A nested Measure section SHALL be valued with section/title with
412 a case-insensitive, text string containing "measure section".
413 (not(parent::cda:ClinicalDocument/cda:component/cda:structuredBody/cda:component/cda:section) or contains(translate(cda:title,"QWERTYUIOPASDFGHJKLZXCVBNM","qwertyuiopasdfghjklzxcvbnm"),"measure section"))</xsl:message>
414 </xsl:otherwise>
415 </xsl:choose>
416
417 <!--ASSERT -->
418<xsl:choose>
419 <xsl:when test="count(.//cda:section[cda:code[@code = &#34;55187-9&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]) = 1"/>
420 <xsl:otherwise>
421 <xsl:message>
422 Error: CONF-QRDA-I-39: A Measure section SHALL contain exactly one nested Reporting
423 Parameters section (as described in Section 2.4.3 Reporting Parameters
424 Section).
425 (count(.//cda:section[cda:code[@code = "55187-9" and @codeSystem="2.16.840.1.113883.6.1"]]) = 1)</xsl:message>
426 </xsl:otherwise>
427 </xsl:choose>
428
429 <!--ASSERT -->
430<xsl:choose>
431 <xsl:when test="count(.//cda:section[cda:code[@code = &#34;55188-7&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]) = 1"/>
432 <xsl:otherwise>
433 <xsl:message>
434 Error: CONF-QRDA-I-40: A Measure section SHALL contain exactly one nested Patient Data
435 section (as described in Section 2.4.4 Patient Data Section).
436 (count(.//cda:section[cda:code[@code = "55188-7" and @codeSystem="2.16.840.1.113883.6.1"]]) = 1)</xsl:message>
437 </xsl:otherwise>
438 </xsl:choose>
439
440 <!--ASSERT -->
441<xsl:choose>
442 <xsl:when test="cda:entry/cda:act[@classCode=&#34;ACT&#34; and @moodCode=&#34;DEF&#34;]"/>
443 <xsl:otherwise>
444 <xsl:message>
445 Error: CONF-QRDA-I-42: Each measure SHALL be represented with act.
446 CONF-QRDA-I-43: For each act in the Measure section, the value for act/@classCode
447 in a measure act SHALL be ACT 2.16.840.1.113883.5.6 ActClass STATIC.
448 CONF-QRDA-I-44: For each act in the Measure section the act/@moodCode in a
449 measure act SHALL be DEF 2.16.840.1.113883.5.1001 ActMood STATIC.
450 (cda:entry/cda:act[@classCode="ACT" and @moodCode="DEF"])</xsl:message>
451 </xsl:otherwise>
452 </xsl:choose>
453 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M6"/>
454 </xsl:template>
455
456 <!--RULE -->
457<xsl:template match="*[cda:code[@code=&#34;55186-1&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]/cda:entry/cda:act[@classCode=&#34;ACT&#34; and @moodCode=&#34;DEF&#34;]"
458 priority="1003"
459 mode="M6">
460
461 <!--ASSERT -->
462<xsl:choose>
463 <xsl:when test="cda:code"/>
464 <xsl:otherwise>
465 <xsl:message>
466 Error: CONF-QRDA-I-45: For each act in the Measure section there SHALL be an act/code
467 reflecting the measure name and version.
468 (cda:code)</xsl:message>
469 </xsl:otherwise>
470 </xsl:choose>
471 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M6"/>
472 </xsl:template>
473
474 <!--RULE -->
475<xsl:template match="*[cda:code[@code=&#34;55185-3&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]"
476 priority="1002"
477 mode="M6">
478
479 <!--ASSERT -->
480<xsl:choose>
481 <xsl:when test="count(.//cda:section[cda:code[@code=&#34;55186-1&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]) = 1"/>
482 <xsl:otherwise>
483 <xsl:message>
484 Error: CONF-QRDA-I-24: The Measure Set section SHALL contain one nested Measure section
485 and SHALL NOT contain more than one nested Measure section.
486 (count(.//cda:section[cda:code[@code="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]]) = 1)</xsl:message>
487 </xsl:otherwise>
488 </xsl:choose>
489
490 <!--ASSERT -->
491<xsl:choose>
492 <xsl:when test="cda:templateId"/>
493 <xsl:otherwise>
494 <xsl:message>
495 Error: CONF-QRDA-I-26: The Measure Set section SHALL contain a templateId uniquely
496 identifying the Measure Set name and version.
497 (cda:templateId)</xsl:message>
498 </xsl:otherwise>
499 </xsl:choose>
500
501 <!--ASSERT -->
502<xsl:choose>
503 <xsl:when test="contains(translate(cda:title,'QWERTYUIOPASDFGHJKLZXCVBNM','qwertyuiopasdfghjklzxcvbnm'),'measure set: ')"/>
504 <xsl:otherwise>
505 <xsl:message>
506 Error: CONF-QRDA-I-29: The Measure Set section SHALL be valued with section/title with a
507 case-insensitive, text string containing "Measure set: &lt;measure set
508 name&gt;".
509 (contains(translate(cda:title,'QWERTYUIOPASDFGHJKLZXCVBNM','qwertyuiopasdfghjklzxcvbnm'),'measure set: '))</xsl:message>
510 </xsl:otherwise>
511 </xsl:choose>
512
513 <!--ASSERT -->
514<xsl:choose>
515 <xsl:when test="count(.//cda:section/cda:code[@code=&#34;55186-1&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]) &gt; 0 "/>
516 <xsl:otherwise>
517 <xsl:message>
518 Error: CONF-QRDA-I-31: The nested Measure section SHALL contain at least one measure that
519 belongs to the measure set.
520 (count(.//cda:section/cda:code[@code="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]) &gt; 0)</xsl:message>
521 </xsl:otherwise>
522 </xsl:choose>
523 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M6"/>
524 </xsl:template>
525
526 <!--RULE -->
527<xsl:template match="*[cda:code[@code=&#34;55187-9&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]"
528 priority="1001"
529 mode="M6">
530
531 <!--ASSERT -->
532<xsl:choose>
533 <xsl:when test="contains(translate(cda:title,&#34;QWERTYUIOPASDFGHJKLZXCVBNM&#34;,&#34;qwertyuiopasdfghjklzxcvbnm&#34;),&#34;reporting parameters&#34;)"/>
534 <xsl:otherwise>
535 <xsl:message>
536 Error: CONF-QRDA-I-49: The Reporting Parameters section SHALL be valued with
537 section/title with a case-insensitive, text string containing "Reporting
538 Parameters".
539 (contains(translate(cda:title,"QWERTYUIOPASDFGHJKLZXCVBNM","qwertyuiopasdfghjklzxcvbnm"),"reporting parameters"))</xsl:message>
540 </xsl:otherwise>
541 </xsl:choose>
542
543 <!--ASSERT -->
544<xsl:choose>
545 <xsl:when test="cda:entry/cda:act[@classCode=&#34;ACT&#34; and @moodCode=&#34;EVN&#34;]/cda:code[@code=&#34;252116004&#34; and @codeSystem=&#34;2.16.840.1.113883.6.96&#34;]"/>
546 <xsl:otherwise>
547 <xsl:message>
548 Error: CONF-QRDA-I-50: The Reporting Parameters section SHALL contain exactly one
549 Observation Parameters Act, represented as an act.
550 CONF-QRDA-I-51: The value for act/@classCode in an Observation Parameters Act
551 SHALL be ACT 2.16.840.1.113883.5.6 ActClass STATIC.
552 CONF-QRDA-I-52: The value for act/@moodCode in an Observation Parameters Act
553 SHALL be EVN 2.16.840.1.113883.5.1001 ActMood STATIC.
554 CONF-QRDA-I-53: The value for act/code SHALL be 252116004 Observation
555 Parameters 2.16.840.1.113883.6.96 SNOMED-CT STATIC.
556 (cda:entry/cda:act[@classCode="ACT" and @moodCode="EVN"]/cda:code[@code="252116004" and @codeSystem="2.16.840.1.113883.6.96"])</xsl:message>
557 </xsl:otherwise>
558 </xsl:choose>
559
560 <!--ASSERT -->
561<xsl:choose>
562 <xsl:when test="cda:entry/cda:act[@classCode=&#34;ACT&#34; and @moodCode=&#34;EVN&#34;][cda:code[@code=&#34;252116004&#34; and @codeSystem=&#34;2.16.840.1.113883.6.96&#34;]]/cda:effectiveTime[cda:low and cda:high]"/>
563 <xsl:otherwise>
564 <xsl:message>
565 Error: CONF-QRDA-I-54: The reporting time period SHALL be represented with an
566 effectiveTime/low element combined with a high element representing
567 respectively the first and last days of the period reported.
568 (cda:entry/cda:act[@classCode="ACT" and @moodCode="EVN"][cda:code[@code="252116004" and @codeSystem="2.16.840.1.113883.6.96"]]/cda:effectiveTime[cda:low and cda:high])</xsl:message>
569 </xsl:otherwise>
570 </xsl:choose>
571 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M6"/>
572 </xsl:template>
573
574 <!--RULE -->
575<xsl:template match="*[cda:code[@code=&#34;55188-7&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]"
576 priority="1000"
577 mode="M6">
578
579 <!--ASSERT -->
580<xsl:choose>
581 <xsl:when test="contains(translate(cda:title,&#34;QWERTYUIOPASDFGHJKLZXCVBNM&#34;,&#34;qwertyuiopasdfghjklzxcvbnm&#34;),&#34;patient data&#34;)"/>
582 <xsl:otherwise>
583 <xsl:message>
584 Error: CONF-QRDA-I-57: The Patient Data section SHALL be valued with section/title with a
585 case-insensitive, text string containing "Patient Data".
586 (contains(translate(cda:title,"QWERTYUIOPASDFGHJKLZXCVBNM","qwertyuiopasdfghjklzxcvbnm"),"patient data"))</xsl:message>
587 </xsl:otherwise>
588 </xsl:choose>
589 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M6"/>
590 </xsl:template>
591 <xsl:template match="text()" priority="-1" mode="M6"/>
592 <xsl:template match="@*|node()" priority="-2" mode="M6">
593 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M6"/>
594 </xsl:template>
595
596 <!--PATTERN p-2.16.840.1.113883.10.20.12-warningsHL7 QRDA Category I Header (Section 2) - warning validation phase-->
597
598
599 <!--RULE -->
600<xsl:template match="*[cda:templateId/@root=&#34;2.16.840.1.113883.10.20.12&#34;]" priority="1000"
601 mode="M7">
602
603 <!--ASSERT -->
604<xsl:choose>
605 <xsl:when test="count(cda:legalAuthenticator) = 1"/>
606 <xsl:otherwise>
607 <xsl:message>
608 Warning: CONF-QRDA-I-14: A QRDA Category I report SHOULD contain exactly one
609 legalAuthenticator element.
610 (count(cda:legalAuthenticator) = 1)</xsl:message>
611 </xsl:otherwise>
612 </xsl:choose>
613 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M7"/>
614 </xsl:template>
615 <xsl:template match="text()" priority="-1" mode="M7"/>
616 <xsl:template match="@*|node()" priority="-2" mode="M7">
617 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M7"/>
618 </xsl:template>
619
620 <!--PATTERN p-2.16.840.1.113883.10.20.12-notesHL7 QRDA Category I Header (Section 2) - note validation phase-->
621
622
623 <!--RULE -->
624<xsl:template match="*[cda:templateId/@root=&#34;2.16.840.1.113883.10.20.12&#34;]" priority="1003"
625 mode="M8">
626
627 <!--ASSERT -->
628<xsl:choose>
629 <xsl:when test="count(cda:component/cda:structuredBody/cda:component/cda:section/cda:code[@code=&#34;55186-1&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]) &gt; 1"/>
630 <xsl:otherwise>
631 <xsl:message>
632 Note: CONF-QRDA-I-21: A QRDA Category I report ... MAY contain
633 more than one non-nested top-level Measure section each containing
634 information about a single measure.
635 (count(cda:component/cda:structuredBody/cda:component/cda:section/cda:code[@code="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]) &gt; 1)</xsl:message>
636 </xsl:otherwise>
637 </xsl:choose>
638
639 <!--ASSERT -->
640<xsl:choose>
641 <xsl:when test=".//cda:section/cda:code[@code=&#34;55185-3&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]"/>
642 <xsl:otherwise>
643 <xsl:message>
644 Note: CONF-QRDA-I-23: A QRDA Category I report MAY contain one or more Measure Set
645 sections.
646 (.//cda:section/cda:code[@code="55185-3" and @codeSystem="2.16.840.1.113883.6.1"])</xsl:message>
647 </xsl:otherwise>
648 </xsl:choose>
649
650 <!--ASSERT -->
651<xsl:choose>
652 <xsl:when test="cda:component/cda:structuredBody/cda:component/cda:section/cda:code[@code=&#34;55186-1&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;] and .//cda:section/cda:code[@code=&#34;55185-3&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]"/>
653 <xsl:otherwise>
654 <xsl:message>
655 Note: CONF-QRDA-I-25: A QRDA Category I report MAY contain both Measure Set sections and
656 individual top-level Measure sections.
657 (cda:component/cda:structuredBody/cda:component/cda:section/cda:code[@code="55186-1" and @codeSystem="2.16.840.1.113883.6.1"] and .//cda:section/cda:code[@code="55185-3" and @codeSystem="2.16.840.1.113883.6.1"])</xsl:message>
658 </xsl:otherwise>
659 </xsl:choose>
660 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M8"/>
661 </xsl:template>
662
663 <!--RULE -->
664<xsl:template match="*[cda:code[@code=&#34;55186-1&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]"
665 priority="1002"
666 mode="M8">
667
668 <!--ASSERT -->
669<xsl:choose>
670 <xsl:when test="cda:text"/>
671 <xsl:otherwise>
672 <xsl:message>
673 Note: CONF-QRDA-I-41: The Measure section MAY contain a section/text element for the
674 description of the measure(s).
675 (cda:text)</xsl:message>
676 </xsl:otherwise>
677 </xsl:choose>
678 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M8"/>
679 </xsl:template>
680
681 <!--RULE -->
682<xsl:template match="*[cda:code[@code=&#34;55186-1&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]/cda:entry/cda:act[@classCode=&#34;ACT&#34; and @moodCode=&#34;DEF&#34;]"
683 priority="1001"
684 mode="M8">
685
686 <!--ASSERT -->
687<xsl:choose>
688 <xsl:when test="cda:text"/>
689 <xsl:otherwise>
690 <xsl:message>
691 Note: CONF-QRDA-I-46: Each measure act MAY contain an act/text element containing a
692 description of the measure.
693 (cda:text)</xsl:message>
694 </xsl:otherwise>
695 </xsl:choose>
696 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M8"/>
697 </xsl:template>
698
699 <!--RULE -->
700<xsl:template match="*[cda:code[@code=&#34;55185-3&#34; and @codeSystem=&#34;2.16.840.1.113883.6.1&#34;]]"
701 priority="1000"
702 mode="M8">
703
704 <!--ASSERT -->
705<xsl:choose>
706 <xsl:when test="cda:text"/>
707 <xsl:otherwise>
708 <xsl:message>
709 Note: CONF-QRDA-I-30: The Measure Set section MAY contain a section/text element for
710 the description of the measure set or MAY contain a formal representation of
711 a description of the measure set.
712 (cda:text)</xsl:message>
713 </xsl:otherwise>
714 </xsl:choose>
715 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M8"/>
716 </xsl:template>
717 <xsl:template match="text()" priority="-1" mode="M8"/>
718 <xsl:template match="@*|node()" priority="-2" mode="M8">
719 <xsl:apply-templates select="*|comment()|processing-instruction()" mode="M8"/>
720 </xsl:template>
721</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.