Skip to content

Commit

Permalink
Test finish phase, plus minor XSLT enhancements and fixes (#1377)
Browse files Browse the repository at this point in the history
XSLT
- Remove template that provides link to source, because metadata phase accomplished that
- Add "[last()]" predicate when passing through elements that cannot appear twice
- Align with schema by passing through revisions, document-id, location, and
  group/link but not control/annotation
- Align with schema for param insertions, `<insert type="param" id-ref="...">`
- Align with schema and spec for keeping items, `<prop name="keep" value="always">`

XSpec
- Add tests at the level of individual templates
  • Loading branch information
galtm authored Jul 25, 2022
1 parent e0809d8 commit 67503b2
Show file tree
Hide file tree
Showing 2 changed files with 591 additions and 185 deletions.
75 changes: 40 additions & 35 deletions src/utils/util/resolver-pipeline/oscal-profile-resolve-finish.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -16,72 +16,72 @@
</xsl:template>

<!-- Finalizing profile resolution into a catalog:
reordering metadata, group and control contents to valid order
removing loose orphan parameters
orphans given inside controls are retained
removing unclaimed inventory
defined as any 'citation' or 'resource' in back matter
without something somewhere linking to it
- Reordering metadata, group and control contents to valid order
- Removing loose orphan parameters
- Orphans given inside controls are retained
- Removing extra elements of types that permit at most one
- Use [last()] instead of [1] to accommodate the case of
replacing a title during modify phase. The modify phase
adds the title following the original one.
- Some "[last()]" expressions are expected to have no effect
if input documents are schema-valid but are included to
avoid producing schema-invalid output.
- Removing unclaimed inventory, defined as any 'resource'
in back matter without something somewhere linking to it
What we are not doing:
removing broken links
remove opqr and xsi namespaces (that happens in the shell)
- Removing broken links
- Remove opr and xsi namespaces (that happens in the shell)
-->
<!-- An XQuery run on a metaschema can return a sequence of instructions
let $where := 'metadata'
for $n in (//*:define-assembly[@name=$where]/*:model/*/(@name | @ref))
return <apply-templates mode="#current" select="{ $n }"/>
Caveat: This query does not account for elements that can occur at most once,
or aliasing via use-name.
-->

<xsl:param name="path-to-source" as="xs:string?"/>

<xsl:template match="metadata/link[@rel='resolution-source']">
<!-- splicing together a path with '/' -->
<link rel="resolution-source" href="{string-join(
($path-to-source[matches(.,'\S')],replace(@href,'.*/','')), '/')}">
<xsl:apply-templates></xsl:apply-templates>
</link>
</xsl:template>

<xsl:template match="catalog">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates mode="#current" select="@*"/>
<xsl:apply-templates mode="#current" select="metadata"/>
<xsl:apply-templates mode="#current" select="metadata[last()]"/>
<xsl:apply-templates mode="#current" select="opr:*"/>
<xsl:apply-templates mode="#current" select="param"/>
<xsl:apply-templates mode="#current" select="control"/>
<xsl:apply-templates mode="#current" select="group"/>
<xsl:apply-templates mode="#current" select="back-matter"/>
<xsl:apply-templates mode="#current" select="back-matter[last()]"/>
</xsl:copy>
</xsl:template>

<xsl:template match="metadata">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates mode="#current" select="@*"/>
<xsl:apply-templates mode="#current" select="title"/>
<xsl:apply-templates mode="#current" select="published"/>
<xsl:apply-templates mode="#current" select="last-modified"/>
<xsl:apply-templates mode="#current" select="version"/>
<xsl:apply-templates mode="#current" select="oscal-version"/>
<xsl:apply-templates mode="#current" select="doc-id"/>
<xsl:apply-templates mode="#current" select="title[last()]"/>
<xsl:apply-templates mode="#current" select="published[last()]"/>
<xsl:apply-templates mode="#current" select="last-modified[last()]"/>
<xsl:apply-templates mode="#current" select="version[last()]"/>
<xsl:apply-templates mode="#current" select="oscal-version[last()]"/>
<xsl:apply-templates mode="#current" select="revisions[last()]"/>
<xsl:apply-templates mode="#current" select="document-id"/>
<xsl:apply-templates mode="#current" select="prop"/>
<xsl:apply-templates mode="#current" select="link"/>
<xsl:apply-templates mode="#current" select="role"/>
<xsl:apply-templates mode="#current" select="location"/>
<xsl:apply-templates mode="#current" select="party"/>
<xsl:apply-templates mode="#current" select="responsible-party"/>
<xsl:apply-templates mode="#current" select="remarks"/>
<xsl:apply-templates mode="#current" select="remarks[last()]"/>
</xsl:copy>
</xsl:template>

<xsl:template match="group">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates mode="#current" select="@*"/>
<xsl:apply-templates mode="#current" select="title"/>
<xsl:apply-templates mode="#current" select="title[last()]"/>
<xsl:apply-templates mode="#current" select="param"/>
<xsl:apply-templates mode="#current" select="prop"/>
<xsl:apply-templates mode="#current" select="link"/>

<xsl:apply-templates mode="#current" select="part"/>
<xsl:apply-templates mode="#current" select="control"/>
Expand All @@ -92,20 +92,23 @@
<xsl:template match="control">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates mode="#current" select="@*"/>
<xsl:apply-templates mode="#current" select="title"/>
<!-- Keep only the last title. There could be multiple titles if
modify phase processed alter/add/title. -->
<xsl:apply-templates mode="#current" select="title[last()]"/>
<xsl:apply-templates mode="#current" select="param"/>
<xsl:apply-templates mode="#current" select="prop"/>
<xsl:apply-templates mode="#current" select="annotation"/>
<xsl:apply-templates mode="#current" select="link"/>
<xsl:apply-templates mode="#current" select="part"/>
<xsl:apply-templates mode="#current" select="control"/>
</xsl:copy>
</xsl:template>

<xsl:key name="param-insertions" match="insert" use="@param-id"/>
<xsl:key name="param-insertions" match="insert[@type='param']" use="@id-ref"/>

<xsl:template match="catalog/param[empty(key('param-insertions',@id))]
| group/param[empty(key('param-insertions',@id))]"/>
<!-- Suppress loose param elements that do not have corresponding insert element(s)
and that do not have an explicit instruction to keep them. -->
<xsl:template match="catalog/param[empty(key('param-insertions',@id))][not(prop[@name='keep'][@value='always'])]
| group/param[empty(key('param-insertions',@id))][not(prop[@name='keep'][@value='always'])]"/>

<!-- Don't copy back-matter wrapper if it has no contents in result -->
<xsl:template match="back-matter">
Expand All @@ -116,6 +119,8 @@

<xsl:key name="cross-reference" match="*[starts-with(@href,'#')]" use="substring-after(@href,'#')"/>

<xsl:template match="resource[empty(key('cross-reference',@uuid))][not(prop[@name='keep']='always')]"/>
<!-- Suppress resource elements that are not referenced and that do not
have an explicit instruction to keep them. -->
<xsl:template match="resource[empty(key('cross-reference',@uuid))][not(prop[@name='keep'][@value='always'])]"/>

</xsl:stylesheet>
Loading

0 comments on commit 67503b2

Please sign in to comment.