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>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>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="2.16.840.1.113883.10.20.12""/>
|
---|
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="2.16.840.1.113883.10.20.12"]" priority="1005"
|
---|
188 | mode="M6">
|
---|
189 |
|
---|
190 | <!--ASSERT -->
|
---|
191 | <xsl:choose>
|
---|
192 | <xsl:when test="cda:realmCode[@code = "US"]"/>
|
---|
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 = "2.16.840.1.113883.1.3" and @extension = "POCD_HD000040"]"/>
|
---|
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="55182-0" and @codeSystem="2.16.840.1.113883.6.1"]"/>
|
---|
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="MSK"]"/>
|
---|
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="S"] or cda:legalAuthenticator/cda:signatureCode[@nullFlavor="MSK"]"/>
|
---|
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="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]) > 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"]) > 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="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]]"
|
---|
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="55185-3" and @codeSystem="2.16.840.1.113883.6.1"]/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="55185-3" and @codeSystem="2.16.840.1.113883.6.1"]/cda:entry) or contains(translate(cda:title,"QWERTYUIOPASDFGHJKLZXCVBNM","qwertyuiopasdfghjklzxcvbnm"),"measure section: ")"/>
|
---|
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 | <measure name>".
|
---|
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,"QWERTYUIOPASDFGHJKLZXCVBNM","qwertyuiopasdfghjklzxcvbnm"),"measure section")"/>
|
---|
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 = "55187-9" and @codeSystem="2.16.840.1.113883.6.1"]]) = 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 = "55188-7" and @codeSystem="2.16.840.1.113883.6.1"]]) = 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="ACT" and @moodCode="DEF"]"/>
|
---|
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="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]]/cda:entry/cda:act[@classCode="ACT" and @moodCode="DEF"]"
|
---|
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="55185-3" and @codeSystem="2.16.840.1.113883.6.1"]]"
|
---|
476 | priority="1002"
|
---|
477 | mode="M6">
|
---|
478 |
|
---|
479 | <!--ASSERT -->
|
---|
480 | <xsl:choose>
|
---|
481 | <xsl:when test="count(.//cda:section[cda:code[@code="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]]) = 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: <measure set
|
---|
508 | name>".
|
---|
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="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]) > 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"]) > 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="55187-9" and @codeSystem="2.16.840.1.113883.6.1"]]"
|
---|
528 | priority="1001"
|
---|
529 | mode="M6">
|
---|
530 |
|
---|
531 | <!--ASSERT -->
|
---|
532 | <xsl:choose>
|
---|
533 | <xsl:when test="contains(translate(cda:title,"QWERTYUIOPASDFGHJKLZXCVBNM","qwertyuiopasdfghjklzxcvbnm"),"reporting parameters")"/>
|
---|
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="ACT" and @moodCode="EVN"]/cda:code[@code="252116004" and @codeSystem="2.16.840.1.113883.6.96"]"/>
|
---|
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="ACT" and @moodCode="EVN"][cda:code[@code="252116004" and @codeSystem="2.16.840.1.113883.6.96"]]/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="55188-7" and @codeSystem="2.16.840.1.113883.6.1"]]"
|
---|
576 | priority="1000"
|
---|
577 | mode="M6">
|
---|
578 |
|
---|
579 | <!--ASSERT -->
|
---|
580 | <xsl:choose>
|
---|
581 | <xsl:when test="contains(translate(cda:title,"QWERTYUIOPASDFGHJKLZXCVBNM","qwertyuiopasdfghjklzxcvbnm"),"patient data")"/>
|
---|
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="2.16.840.1.113883.10.20.12"]" 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="2.16.840.1.113883.10.20.12"]" 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="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]) > 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"]) > 1)</xsl:message>
|
---|
636 | </xsl:otherwise>
|
---|
637 | </xsl:choose>
|
---|
638 |
|
---|
639 | <!--ASSERT -->
|
---|
640 | <xsl:choose>
|
---|
641 | <xsl:when test=".//cda:section/cda:code[@code="55185-3" and @codeSystem="2.16.840.1.113883.6.1"]"/>
|
---|
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="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"]"/>
|
---|
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="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]]"
|
---|
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="55186-1" and @codeSystem="2.16.840.1.113883.6.1"]]/cda:entry/cda:act[@classCode="ACT" and @moodCode="DEF"]"
|
---|
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="55185-3" and @codeSystem="2.16.840.1.113883.6.1"]]"
|
---|
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>
|
---|