Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profile resolver: Test finish phase, plus minor XSLT enhancements and fixes #1377

Merged
merged 1 commit into from
Jul 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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