Skip to content
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
18 changes: 18 additions & 0 deletions __data__/gml_id.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:gml="http://www.opengis.net/gml/3.2"
targetNamespace="http://www.opengis.net/gml/3.2"
elementFormDefault="qualified">

<xs:attribute name="id" type="xs:ID"/>

<xs:element name="FunctionalZone">
<xs:complexType>
<xs:sequence>
<xs:element name="GLOBALID" type="xs:string"/>
</xs:sequence>
<xs:attribute ref="gml:id"/>
</xs:complexType>
</xs:element>

</xs:schema>
39 changes: 39 additions & 0 deletions __tests__/XMLValidatior.js
Original file line number Diff line number Diff line change
Expand Up @@ -569,5 +569,44 @@ describe ('sequence', () => {

})

})

describe ('gml:id attribute ref', () => {

const xs = new XMLSchemata (Path.join (__dirname, '..', '__data__', 'gml_id.xsd'))

test ('gml:id accepted on FunctionalZone', () => {

new XMLParser ({xs}).process ([
`<gml:FunctionalZone xmlns:gml="http://www.opengis.net/gml/3.2"`,
` gml:id="FunctionalZone.0">`,
`<gml:GLOBALID>8b2457c9-85c4-466a-a14b-b20856527718</gml:GLOBALID>`,
`</gml:FunctionalZone>`,
].join (''))

})

test ('bare id rejected (namespace required)', () => {

expect (() => new XMLParser ({xs}).process ([
`<gml:FunctionalZone xmlns:gml="http://www.opengis.net/gml/3.2"`,
` id="FunctionalZone.0">`,
`<gml:GLOBALID>8b2457c9-85c4-466a-a14b-b20856527718</gml:GLOBALID>`,
`</gml:FunctionalZone>`,
].join (''))).toThrow ('Unknown attribute')

})

test ('wrong namespace rejected', () => {

expect (() => new XMLParser ({xs}).process ([
`<gml:FunctionalZone xmlns:gml="http://www.opengis.net/gml/3.2"`,
` xmlns:other="http://other.ns"`,
` other:id="FunctionalZone.0">`,
`<gml:GLOBALID>8b2457c9-85c4-466a-a14b-b20856527718</gml:GLOBALID>`,
`</gml:FunctionalZone>`,
].join (''))).toThrow ('Unknown attribute')

})

})
36 changes: 32 additions & 4 deletions lib/validation/XMLValidationState.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,39 @@ class XMLValidationState {

}

resolveAttribute (name, attributesMap) {

const {attributes} = this.anyType

if (attributes.has (name)) {

const def = attributes.get (name)

if (!def.targetNamespace || def.targetNamespace === attributesMap.getNamespaceURI (name)) return def

}

const localName = attributesMap.getLocalName (name); if (localName === name) return null

const def = attributes.get (localName); if (!def) return null

if (def.targetNamespace !== attributesMap.getNamespaceURI (name)) return null

return def

}

validateAttributes (attributesMap) {

const {attributes, isAnyAttributeAllowed} = this.anyType

const matched = new Set ()

for (const [name, value] of attributesMap) {

if (!attributes.has (name)) {
const def = this.resolveAttribute (name, attributesMap)

if (!def) {

if (isAnyAttributeAllowed) continue

Expand All @@ -131,8 +157,10 @@ class XMLValidationState {
throw Error (`Unknown attribute: "${name}"`)

}

const def = attributes.get (name), {attributes: {fixed, type}} = def

matched.add (def)

const {attributes: {fixed, type}} = def

if (typeof fixed === 'string' && value !== fixed) throw Error (`The attribute "${name}" must have the value "${fixed}", not "${value}"`)

Expand Down Expand Up @@ -164,7 +192,7 @@ class XMLValidationState {

}

for (const [name, def] of attributes) if (!attributesMap.has (name)) {
for (const [name, def] of attributes) if (!matched.has (def)) {

if (def.attributes.use === 'required') throw Error (`Missing required attribute: "${name}"`)

Expand Down
Loading