<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://scap.nist.gov/schema/asset-reporting-format/1.1"
    xmlns:ai="http://scap.nist.gov/schema/asset-identification/1.1"
    xmlns:core="http://scap.nist.gov/schema/reporting-core/1.1"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    targetNamespace="http://scap.nist.gov/schema/asset-reporting-format/1.1"
    elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.1.0-rc1">
    <xs:annotation>
        <xs:appinfo>
            <schema>Asset Reporting Format</schema>
            <author>David Waltermire, Adam Halbardier, John Wunder</author>
            <version>1.1.0 - release candidate 1</version>
            <date>2010-11-30</date>
            <sch:schema queryBinding="xslt2" xmlns:sch="http://purl.oclc.org/dsdl/schematron">
                <sch:ns prefix="xml" uri="http://www.w3.org/XML/1998/namespace" />
                <sch:ns prefix="xsd" uri="http://www.w3.org/2001/XMLSchema" />
                <sch:ns prefix="arf" uri="http://scap.nist.gov/schema/asset-reporting-format/1.1" />
                <sch:ns prefix="core" uri="http://scap.nist.gov/schema/reporting-core/1.1" />
                <sch:ns prefix="ai" uri="http://scap.nist.gov/schema/asset-identification/1.1" />
                <sch:ns prefix="fn" uri="http://www.w3.org/2005/xpath-functions" />
                <sch:ns prefix="xcf" uri="nist:scap:arf:xslt:function" />
                <sch:pattern>
                    <sch:let name="arf-namespace" value="string('http://scap.nist.gov/vocabulary/arf/relationships/1.0#')" />
                    <sch:rule context="core:relationship[fn:resolve-QName(@type, current()) eq fn:QName($arf-namespace,'isAbout' )]">
                        <sch:assert test="exists(ancestor::arf:asset-report-collection/arf:reports/arf:report[@id eq current()/@subject])">
                            <sch:value-of select="xcf:controlled-vocab-error-domain(current(),'report')" />
                        </sch:assert>
                        <sch:assert test="every $m in core:ref satisfies current()/ancestor::arf:asset-report-collection/ai:assets/ai:asset[@id eq $m]">
                            <sch:value-of select="xcf:controlled-vocab-error-range(current(),'asset')" />
                        </sch:assert>
                    </sch:rule>
                    <sch:rule context="core:relationship[fn:resolve-QName(@type, current()) eq fn:QName($arf-namespace,'retrievedFrom' )]">
                        <sch:assert test="exists(ancestor::arf:asset-report-collection/arf:reports/arf:report[@id eq current()/@subject])">
                            <sch:value-of select="xcf:controlled-vocab-error-domain(current(),'report')" />
                        </sch:assert>
                        <sch:assert test="every $m in core:ref satisfies current()/ancestor::arf:asset-report-collection/ai:assets/ai:asset[@id eq $m]">
                            <sch:value-of select="xcf:controlled-vocab-error-range(current(),'asset')" />
                        </sch:assert>
                    </sch:rule>
                    <sch:rule context="core:relationship[fn:resolve-QName(@type, current()) eq fn:QName($arf-namespace,'createdBy' )]">
                        <sch:assert test="exists(ancestor::arf:asset-report-collection/arf:reports/arf:report[@id eq current()/@subject])">
                            <sch:value-of select="xcf:controlled-vocab-error-domain(current(),'report')" />
                        </sch:assert>
                        <sch:assert test="every $m in core:ref satisfies current()/ancestor::arf:asset-report-collection/ai:assets/ai:asset[@id eq $m]">
                            <sch:value-of select="xcf:controlled-vocab-error-range(current(),'asset')" />
                        </sch:assert>
                    </sch:rule>
                    <sch:rule context="core:relationship[fn:resolve-QName(@type, current()) eq fn:QName($arf-namespace,'hasSource' )]">
                        <sch:assert test="exists(ancestor::arf:asset-report-collection/arf:reports/arf:report[@id eq current()/@subject])">
                            <sch:value-of select="xcf:controlled-vocab-error-domain(current(),'report')" />
                        </sch:assert>
                        <sch:assert test="every $m in core:ref satisfies current()/ancestor::arf:asset-report-collection/ai:assets/ai:asset[@id eq $m]">
                            <sch:value-of select="xcf:controlled-vocab-error-range(current(),'asset')" />
                        </sch:assert>
                    </sch:rule>
                    <sch:rule context="core:relationship[fn:resolve-QName(@type, current()) eq fn:QName($arf-namespace,'recordedBy' )]">
                        <sch:assert test="exists(ancestor::arf:asset-report-collection/arf:reports/arf:report[@id eq current()/@subject])">
                            <sch:value-of select="xcf:controlled-vocab-error-domain(current(),'report')" />
                        </sch:assert>
                        <sch:assert test="every $m in core:ref satisfies current()/ancestor::arf:asset-report-collection/ai:assets/ai:asset[@id eq $m]">
                            <sch:value-of select="xcf:controlled-vocab-error-range(current(),'asset')" />
                        </sch:assert>
                    </sch:rule>
                    <sch:rule context="core:relationship[fn:resolve-QName(@type, current()) eq fn:QName($arf-namespace,'initiatedBy' )]">
                        <sch:assert test="exists(ancestor::arf:asset-report-collection/arf:reports/arf:report[@id eq current()/@subject])">
                            <sch:value-of select="xcf:controlled-vocab-error-domain(current(),'report')" />
                        </sch:assert>
                        <sch:assert test="every $m in core:ref satisfies current()/ancestor::arf:asset-report-collection/ai:assets/ai:asset[@id eq $m]">
                            <sch:value-of select="xcf:controlled-vocab-error-range(current(),'asset')" />
                        </sch:assert>
                    </sch:rule>
                    <sch:rule context="core:relationship[fn:resolve-QName(@type, current()) eq fn:QName($arf-namespace,'createdFor' )]">
                        <sch:assert test="exists(ancestor::arf:asset-report-collection/arf:reports/arf:report[@id eq current()/@subject])">
                            <sch:value-of select="xcf:controlled-vocab-error-domain(current(),'report')" />
                        </sch:assert>
                        <sch:assert test="every $m in core:ref satisfies current()/ancestor::arf:asset-report-collection/arf:report-requests/arf:report-request[@id eq $m]">
                            <sch:value-of select="xcf:controlled-vocab-error-range(current(),'report-request')" />
                        </sch:assert>
                    </sch:rule>
                    <sch:rule context="core:relationship[fn:resolve-QName(@type, current()) eq fn:QName($arf-namespace,'hasMetadata' )]">
                        <sch:assert test="exists(ancestor::arf:asset-report-collection/arf:reports/arf:report[@id eq current()/@subject])">
                            <sch:value-of select="xcf:controlled-vocab-error-domain(current(),'report')" />
                        </sch:assert>
                        <sch:assert test="every $m in core:ref satisfies current()/ancestor::arf:asset-report-collection/arf:reports/arf:report[@id eq $m]">
                            <sch:value-of select="xcf:controlled-vocab-error-range(current(),'report')" />
                        </sch:assert>
                    </sch:rule>
                </sch:pattern>
                <xsl:function name="xcf:controlled-vocab-error-domain" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xcf="nist:scap:arf:xslt:function" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/XSL/Transform">
                    <xsl:param name="node" />
                    <xsl:param name="refName" />
                    <xsl:value-of select="concat(concat(concat(concat(string('All @subject attribute in a relationship of type '),namespace-uri-from-QName(resolve-QName($node/@type, $node))),local-name-from-QName(resolve-QName($node/@type, $node))),string(' must reference a ')),$refName)" />
                </xsl:function>
                <xsl:function name="xcf:controlled-vocab-error-range" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xcf="nist:scap:arf:xslt:function" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/XSL/Transform">
                    <xsl:param name="node" />
                    <xsl:param name="refName" />
                    <xsl:value-of select="concat(concat(concat(concat(string('All &lt;ref&gt; elements in a relationship of type '),namespace-uri-from-QName(resolve-QName($node/@type, $node))),local-name-from-QName(resolve-QName($node/@type, $node))),string(' must reference a ')),$refName)" />
                </xsl:function>
            </sch:schema>
        </xs:appinfo>
    </xs:annotation>
    <xs:import namespace="http://scap.nist.gov/schema/asset-identification/1.1" schemaLocation="/schema/asset-identification/1.1/asset-identification_1.1.0-rc1.xsd" />
    <xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="https://www.w3.org/1999/xlink.xsd" />
    <xs:import namespace="http://scap.nist.gov/schema/reporting-core/1.1" schemaLocation="/schema/reporting-core/1.1/reporting_core-rc1.xsd" />
    <xs:element name="asset-report-collection">
        <xs:annotation>
            <xs:documentation>The top-level report element.</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="core:relationships-container-type">
                    <xs:sequence>
                        <xs:element name="report-requests" minOccurs="0">
                            <xs:annotation>
                                <xs:documentation>Contains one or more requests for reports. Each report request must be referenced in a relationship on a report in the same asset-report-collection.</xs:documentation>
                            </xs:annotation>
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="report-request" type="tns:ReportRequestType" maxOccurs="unbounded">
                                    </xs:element>
                                </xs:sequence>
                            </xs:complexType>
                        </xs:element>
                        <xs:element ref="ai:assets">
                            <xs:annotation>
                                <xs:documentation>Contains the representation of one or more assets represented using the Asset Identification format.</xs:documentation>
                            </xs:annotation>
                        </xs:element>
                        <xs:element name="reports">
                            <xs:annotation>
                                <xs:documentation>Contains one or more reports.</xs:documentation>
                            </xs:annotation>
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="report" type="tns:ReportType" maxOccurs="unbounded">
                                        <xs:annotation>
                                            <xs:documentation>Contains a report, which is composed of zero or more relationships and a content payload.</xs:documentation>
                                        </xs:annotation>
                                    </xs:element>
                                </xs:sequence>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:anyAttribute namespace="##other">
                        <xs:annotation>
                            <xs:documentation>A placeholder so that content creators can add attributes as desired.</xs:documentation>
                        </xs:annotation>
                    </xs:anyAttribute>
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
        <xs:key name="idKey">
            <xs:selector xpath="tns:report-requests/tns:report-request|ai:assets/ai:asset|tns:reports/tns:report" />
            <xs:field xpath="@id" />
        </xs:key>
        <xs:keyref name="relSubjKeyRef" refer="tns:idKey">
            <xs:selector xpath="core:relationships/core:relationship" />
            <xs:field xpath="@subject" />
        </xs:keyref>
        <xs:keyref name="relObjKeyRef" refer="tns:idKey">
            <xs:selector xpath="core:relationships/core:relationship/core:ref" />
            <xs:field xpath="." />
        </xs:keyref>
    </xs:element>
    <xs:complexType name="ReportRequestType">
        <xs:sequence>
            <xs:any namespace="##other">
                <xs:annotation>
                    <xs:documentation>Holds the content of a report request.</xs:documentation>
                </xs:annotation>
            </xs:any>
        </xs:sequence>
        <xs:attribute name="id" type="xs:NCName" use="required">
            <xs:annotation>
                <xs:documentation>An internal ID to identify this report request.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:anyAttribute namespace="##other">
            <xs:annotation>
                <xs:documentation>A placeholder so that content creators can add attributes as desired.</xs:documentation>
            </xs:annotation>
        </xs:anyAttribute>
    </xs:complexType>
    <xs:complexType name="ReportType">
        <xs:sequence>
            <xs:choice>
                <xs:element name="content">
                    <xs:annotation>
                        <xs:documentation>Contains the content of the report.</xs:documentation>
                    </xs:annotation>
                    <xs:complexType>
                        <xs:sequence>
                            <xs:any namespace="##other" processContents="lax" />
                        </xs:sequence>
                        <xs:attribute name="data-valid-start-date" type="xs:date" />
                        <xs:attribute name="data-valid-end-date" type="xs:date" />
                        <xs:anyAttribute namespace="##other">
                            <xs:annotation>
                                <xs:documentation>A placeholder so that content creators can add attributes as desired.</xs:documentation>
                            </xs:annotation>
                        </xs:anyAttribute>
                    </xs:complexType>
                </xs:element>
                <xs:element name="remote-resource">
                    <xs:annotation>
                        <xs:documentation>Links to content stored external to this report.</xs:documentation>
                    </xs:annotation>
                    <xs:complexType>
                        <xs:attribute ref="xlink:type" use="required" fixed="simple">
                            <xs:annotation>
                                <xs:documentation>Fixed as a simple XLink.</xs:documentation>
                            </xs:annotation>
                        </xs:attribute>
                        <xs:attribute ref="xlink:href" use="required">
                            <xs:annotation>
                                <xs:documentation>A URI to the remote content. Producers and consumers should both know how to resolve the URI in order to be interoperable.</xs:documentation>
                            </xs:annotation>
                        </xs:attribute>
                        <xs:anyAttribute namespace="##other">
                            <xs:annotation>
                                <xs:documentation>A placeholder so that content creators can add attributes as desired.</xs:documentation>
                            </xs:annotation>
                        </xs:anyAttribute>
                    </xs:complexType>
                </xs:element>
            </xs:choice>
        </xs:sequence>
        <xs:attribute name="id" type="xs:NCName" use="required">
            <xs:annotation>
                <xs:documentation>An internal ID to identify this report.</xs:documentation>
            </xs:annotation>
        </xs:attribute>
        <xs:anyAttribute namespace="##other">
            <xs:annotation>
                <xs:documentation>A placeholder so that content creators can add attributes as desired.</xs:documentation>
            </xs:annotation>
        </xs:anyAttribute>
    </xs:complexType>
</xs:schema>
