A strict or lax wildcard must resolve elements declared in schema documents an instance points at through xsi:schemaLocation, which the main schema need not import. validate(_:schemaLoader:) now reads the instance's xsi:schemaLocation and xsi:noNamespaceSchemaLocation hints, loads and compiles each referenced document through the loader, and merges its global declarations in (the primary schema wins on conflict). The plain validate(_:) is unchanged; the XSTS runner resolves hints relative to the instance file. XSTS: valid instances rejected 308 to 288 (the particle clusters whose wildcard-matched elements live in a separate, instance-referenced schema). Baseline updated; regression tests cover cross-document resolution, the loaded type being enforced, and strict failure without the loader. Refs #147, #129.
55 lines
2.2 KiB
Swift
55 lines
2.2 KiB
Swift
@testable import PureXML
|
|
import Testing
|
|
|
|
/// `validate(_:schemaLoader:)` honors an instance's `xsi:schemaLocation`,
|
|
/// loading the referenced schema documents so a strict (or lax) wildcard can
|
|
/// resolve elements declared in another document (#147, XSTS particles set).
|
|
@Suite("Multi-document validation via xsi:schemaLocation")
|
|
struct SchemaMultiDocumentTests {
|
|
private let mainXSD = """
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
targetNamespace="urn:a" xmlns:a="urn:a">
|
|
<xs:element name="doc">
|
|
<xs:complexType>
|
|
<xs:sequence>
|
|
<xs:any namespace="##other" processContents="strict" minOccurs="1" maxOccurs="3"/>
|
|
</xs:sequence>
|
|
</xs:complexType>
|
|
</xs:element>
|
|
</xs:schema>
|
|
"""
|
|
|
|
private let otherXSD = """
|
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:b">
|
|
<xs:element name="thing" type="xs:int"/>
|
|
</xs:schema>
|
|
"""
|
|
|
|
private let instance = """
|
|
<a:doc xmlns:a="urn:a" xmlns:b="urn:b"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="urn:b other.xsd"><b:thing>5</b:thing></a:doc>
|
|
"""
|
|
|
|
@Test("A strict wildcard resolves an element from the xsi:schemaLocation schema")
|
|
func test_resolvesAcrossDocuments() throws {
|
|
let doc = try PureXML.Schema.Document(mainXSD)
|
|
let loader: (String) -> String? = { [otherXSD] in $0 == "other.xsd" ? otherXSD : nil }
|
|
#expect(try doc.validate(instance, schemaLoader: loader).isEmpty)
|
|
}
|
|
|
|
@Test("The loaded declaration's type is still enforced")
|
|
func test_loadedTypeEnforced() throws {
|
|
let doc = try PureXML.Schema.Document(mainXSD)
|
|
let loader: (String) -> String? = { [otherXSD] in $0 == "other.xsd" ? otherXSD : nil }
|
|
let bad = instance.replacingOccurrences(of: "<b:thing>5</b:thing>", with: "<b:thing>notint</b:thing>")
|
|
#expect(try !doc.validate(bad, schemaLoader: loader).isEmpty)
|
|
}
|
|
|
|
@Test("Without the loader a strict wildcard cannot resolve the element")
|
|
func test_strictUnresolvedWithoutLoader() throws {
|
|
let doc = try PureXML.Schema.Document(mainXSD)
|
|
#expect(try !doc.validate(instance).isEmpty)
|
|
}
|
|
}
|