|
16 | 16 | </xsl:template> |
17 | 17 |
|
18 | 18 | <!-- Finalizing profile resolution into a catalog: |
19 | | - reordering metadata, group and control contents to valid order |
20 | | - removing loose orphan parameters |
21 | | - orphans given inside controls are retained |
22 | | - removing unclaimed inventory |
23 | | - defined as any 'citation' or 'resource' in back matter |
24 | | - without something somewhere linking to it |
25 | | -
|
| 19 | + - Reordering metadata, group and control contents to valid order |
| 20 | + - Removing loose orphan parameters |
| 21 | + - Orphans given inside controls are retained |
| 22 | + - Removing extra elements of types that permit at most one |
| 23 | + - Use [last()] instead of [1] to accommodate the case of |
| 24 | + replacing a title during modify phase. The modify phase |
| 25 | + adds the title following the original one. |
| 26 | + - Some "[last()]" expressions are expected to have no effect |
| 27 | + if input documents are schema-valid but are included to |
| 28 | + avoid producing schema-invalid output. |
| 29 | + - Removing unclaimed inventory, defined as any 'resource' |
| 30 | + in back matter without something somewhere linking to it |
26 | 31 |
|
27 | 32 | What we are not doing: |
28 | | - removing broken links |
29 | | - remove opqr and xsi namespaces (that happens in the shell) |
| 33 | + - Removing broken links |
| 34 | + - Remove opr and xsi namespaces (that happens in the shell) |
30 | 35 | --> |
31 | 36 | <!-- An XQuery run on a metaschema can return a sequence of instructions |
32 | 37 |
|
33 | 38 | let $where := 'metadata' |
34 | 39 | for $n in (//*:define-assembly[@name=$where]/*:model/*/(@name | @ref)) |
35 | 40 | return <apply-templates mode="#current" select="{ $n }"/> |
36 | 41 |
|
| 42 | + Caveat: This query does not account for elements that can occur at most once, |
| 43 | + or aliasing via use-name. |
37 | 44 | --> |
38 | 45 |
|
39 | | - <xsl:param name="path-to-source" as="xs:string?"/> |
40 | | - |
41 | | - <xsl:template match="metadata/link[@rel='resolution-source']"> |
42 | | - <!-- splicing together a path with '/' --> |
43 | | - <link rel="resolution-source" href="{string-join( |
44 | | - ($path-to-source[matches(.,'\S')],replace(@href,'.*/','')), '/')}"> |
45 | | - <xsl:apply-templates></xsl:apply-templates> |
46 | | - </link> |
47 | | - </xsl:template> |
48 | | - |
49 | 46 | <xsl:template match="catalog"> |
50 | 47 | <xsl:copy copy-namespaces="no"> |
51 | 48 | <xsl:apply-templates mode="#current" select="@*"/> |
52 | | - <xsl:apply-templates mode="#current" select="metadata"/> |
| 49 | + <xsl:apply-templates mode="#current" select="metadata[last()]"/> |
53 | 50 | <xsl:apply-templates mode="#current" select="opr:*"/> |
54 | 51 | <xsl:apply-templates mode="#current" select="param"/> |
55 | 52 | <xsl:apply-templates mode="#current" select="control"/> |
56 | 53 | <xsl:apply-templates mode="#current" select="group"/> |
57 | | - <xsl:apply-templates mode="#current" select="back-matter"/> |
| 54 | + <xsl:apply-templates mode="#current" select="back-matter[last()]"/> |
58 | 55 | </xsl:copy> |
59 | 56 | </xsl:template> |
60 | 57 |
|
61 | 58 | <xsl:template match="metadata"> |
62 | 59 | <xsl:copy copy-namespaces="no"> |
63 | 60 | <xsl:apply-templates mode="#current" select="@*"/> |
64 | | - <xsl:apply-templates mode="#current" select="title"/> |
65 | | - <xsl:apply-templates mode="#current" select="published"/> |
66 | | - <xsl:apply-templates mode="#current" select="last-modified"/> |
67 | | - <xsl:apply-templates mode="#current" select="version"/> |
68 | | - <xsl:apply-templates mode="#current" select="oscal-version"/> |
69 | | - <xsl:apply-templates mode="#current" select="doc-id"/> |
| 61 | + <xsl:apply-templates mode="#current" select="title[last()]"/> |
| 62 | + <xsl:apply-templates mode="#current" select="published[last()]"/> |
| 63 | + <xsl:apply-templates mode="#current" select="last-modified[last()]"/> |
| 64 | + <xsl:apply-templates mode="#current" select="version[last()]"/> |
| 65 | + <xsl:apply-templates mode="#current" select="oscal-version[last()]"/> |
| 66 | + <xsl:apply-templates mode="#current" select="revisions[last()]"/> |
| 67 | + <xsl:apply-templates mode="#current" select="document-id"/> |
70 | 68 | <xsl:apply-templates mode="#current" select="prop"/> |
71 | 69 | <xsl:apply-templates mode="#current" select="link"/> |
72 | 70 | <xsl:apply-templates mode="#current" select="role"/> |
| 71 | + <xsl:apply-templates mode="#current" select="location"/> |
73 | 72 | <xsl:apply-templates mode="#current" select="party"/> |
74 | 73 | <xsl:apply-templates mode="#current" select="responsible-party"/> |
75 | | - <xsl:apply-templates mode="#current" select="remarks"/> |
| 74 | + <xsl:apply-templates mode="#current" select="remarks[last()]"/> |
76 | 75 | </xsl:copy> |
77 | 76 | </xsl:template> |
78 | 77 |
|
79 | 78 | <xsl:template match="group"> |
80 | 79 | <xsl:copy copy-namespaces="no"> |
81 | 80 | <xsl:apply-templates mode="#current" select="@*"/> |
82 | | - <xsl:apply-templates mode="#current" select="title"/> |
| 81 | + <xsl:apply-templates mode="#current" select="title[last()]"/> |
83 | 82 | <xsl:apply-templates mode="#current" select="param"/> |
84 | 83 | <xsl:apply-templates mode="#current" select="prop"/> |
| 84 | + <xsl:apply-templates mode="#current" select="link"/> |
85 | 85 |
|
86 | 86 | <xsl:apply-templates mode="#current" select="part"/> |
87 | 87 | <xsl:apply-templates mode="#current" select="control"/> |
|
92 | 92 | <xsl:template match="control"> |
93 | 93 | <xsl:copy copy-namespaces="no"> |
94 | 94 | <xsl:apply-templates mode="#current" select="@*"/> |
95 | | - <xsl:apply-templates mode="#current" select="title"/> |
| 95 | + <!-- Keep only the last title. There could be multiple titles if |
| 96 | + modify phase processed alter/add/title. --> |
| 97 | + <xsl:apply-templates mode="#current" select="title[last()]"/> |
96 | 98 | <xsl:apply-templates mode="#current" select="param"/> |
97 | 99 | <xsl:apply-templates mode="#current" select="prop"/> |
98 | | - <xsl:apply-templates mode="#current" select="annotation"/> |
99 | 100 | <xsl:apply-templates mode="#current" select="link"/> |
100 | 101 | <xsl:apply-templates mode="#current" select="part"/> |
101 | 102 | <xsl:apply-templates mode="#current" select="control"/> |
102 | 103 | </xsl:copy> |
103 | 104 | </xsl:template> |
104 | 105 |
|
105 | | - <xsl:key name="param-insertions" match="insert" use="@param-id"/> |
| 106 | + <xsl:key name="param-insertions" match="insert[@type='param']" use="@id-ref"/> |
106 | 107 |
|
107 | | - <xsl:template match="catalog/param[empty(key('param-insertions',@id))] |
108 | | - | group/param[empty(key('param-insertions',@id))]"/> |
| 108 | + <!-- Suppress loose param elements that do not have corresponding insert element(s) |
| 109 | + and that do not have an explicit instruction to keep them. --> |
| 110 | + <xsl:template match="catalog/param[empty(key('param-insertions',@id))][not(prop[@name='keep'][@value='always'])] |
| 111 | + | group/param[empty(key('param-insertions',@id))][not(prop[@name='keep'][@value='always'])]"/> |
109 | 112 |
|
110 | 113 | <!-- Don't copy back-matter wrapper if it has no contents in result --> |
111 | 114 | <xsl:template match="back-matter"> |
|
116 | 119 |
|
117 | 120 | <xsl:key name="cross-reference" match="*[starts-with(@href,'#')]" use="substring-after(@href,'#')"/> |
118 | 121 |
|
119 | | - <xsl:template match="resource[empty(key('cross-reference',@uuid))][not(prop[@name='keep']='always')]"/> |
| 122 | + <!-- Suppress resource elements that are not referenced and that do not |
| 123 | + have an explicit instruction to keep them. --> |
| 124 | + <xsl:template match="resource[empty(key('cross-reference',@uuid))][not(prop[@name='keep'][@value='always'])]"/> |
120 | 125 |
|
121 | 126 | </xsl:stylesheet> |
0 commit comments