The top-level declaration constraints (a global element/attribute may not carry the local-only form/use/ref/minOccurs/maxOccurs; a global definition needs a name) apply to every document in a schema composition, but the existing check ran only over the document being compiled. A violation inside an xs:include, xs:import, or xs:redefine target was therefore missed and the composed schema wrongly accepted. The same global-component check now runs over the other schema-document roots in the composition (the main document is excluded as already covered; redefine entries are skipped because each schema root walks its own redefine children). The constraint is absolute and position-independent, so no valid schema is newly rejected; libxml2 rejects both cases for the same reason. Catches attQ016 (import) and attQ018 (include). XSTS invalid-schemas- accepted 20 to 18, valid-schemas-rejected held at 0.
72 lines
2.9 KiB
Swift
72 lines
2.9 KiB
Swift
import Testing
|
|
@testable import PureXML
|
|
|
|
/// The top-level (global) declaration constraints apply to every document in a
|
|
/// schema composition, not only the one being compiled. The `form` attribute is
|
|
/// permitted only on a LOCAL element or attribute declaration; a global one that
|
|
/// carries it is invalid (XSD 1.0 schema-for-schemas: `topLevelAttribute` and
|
|
/// `topLevelElement` have no `form`). When the offending declaration lives in an
|
|
/// included or imported document the check used to be skipped, so the schema was
|
|
/// wrongly accepted. Mirrors XSTS attQ016 (import) and attQ018 (include).
|
|
@Suite("global form in included/imported documents")
|
|
struct SchemaContainerTopLevelFormTests {
|
|
private func compiles(_ main: String, _ files: [String: String]) -> Bool {
|
|
(try? PureXML.Schema.Document(main, schemaLoader: { files[$0] })) != nil
|
|
}
|
|
|
|
private let main = """
|
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
targetNamespace="urn:t" xmlns:t="urn:t">
|
|
<xsd:include schemaLocation="lib.xsd"/>
|
|
<xsd:element name="doc" type="xsd:string"/>
|
|
</xsd:schema>
|
|
"""
|
|
|
|
@Test("an included document with form on a global attribute is rejected")
|
|
func test_includedGlobalAttributeForm() {
|
|
let lib = """
|
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:t">
|
|
<xsd:attribute name="ga" form="qualified"/>
|
|
</xsd:schema>
|
|
"""
|
|
#expect(!compiles(main, ["lib.xsd": lib]))
|
|
}
|
|
|
|
@Test("an included document with form on a global element is rejected")
|
|
func test_includedGlobalElementForm() {
|
|
let lib = """
|
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:t">
|
|
<xsd:element name="ge" form="qualified" type="xsd:string"/>
|
|
</xsd:schema>
|
|
"""
|
|
#expect(!compiles(main, ["lib.xsd": lib]))
|
|
}
|
|
|
|
@Test("the same global attribute without form keeps the composition valid")
|
|
func test_includedGlobalAttributeNoForm() {
|
|
let lib = """
|
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:t">
|
|
<xsd:attribute name="ga" type="xsd:string"/>
|
|
</xsd:schema>
|
|
"""
|
|
#expect(compiles(main, ["lib.xsd": lib]))
|
|
}
|
|
|
|
@Test("an imported document with form on a global attribute is rejected")
|
|
func test_importedGlobalAttributeForm() {
|
|
let importer = """
|
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
|
targetNamespace="urn:t" xmlns:t="urn:t">
|
|
<xsd:import namespace="urn:i" schemaLocation="imp.xsd"/>
|
|
<xsd:element name="doc" type="xsd:string"/>
|
|
</xsd:schema>
|
|
"""
|
|
let imp = """
|
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:i">
|
|
<xsd:attribute name="ia" form="qualified"/>
|
|
</xsd:schema>
|
|
"""
|
|
#expect(!compiles(importer, ["imp.xsd": imp]))
|
|
}
|
|
}
|