From e1b4634fa463cd59fa17862557ef3dc09d64c287 Mon Sep 17 00:00:00 2001 From: Edward Nash Date: Fri, 29 Oct 2021 15:42:50 +0200 Subject: [PATCH 1/2] Correct parsing multi-properties with attributes When parsing GML then conversion of properties containing XML attributes to objects with a _content_ property must occur before the handling of multiple attributes (conversion/adding to an array), as otherwise the _content_ property and attributes are set on the array and not on the array element. Prior to this change, only multiple properties without attributes could be correctly parsed. Example problemeatic GML section: Resulting property as JSON extract after this change: { "Link": [ { "_content_": undefined, "xlink:href": "http://example.com/a", }, { "_content_": undefined, "xlink:href": "http://example.com/b" } ] } Prior to this change, the _content_ property and the properties for the XML attributes would be set on the resulting JS Array object, with previous entries being represented as nested arrays. --- src/ol/format/GMLBase.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ol/format/GMLBase.js b/src/ol/format/GMLBase.js index d2b6cfd912..833dbbb873 100644 --- a/src/ol/format/GMLBase.js +++ b/src/ol/format/GMLBase.js @@ -304,6 +304,15 @@ class GMLBase extends XMLFeature { } } + const len = n.attributes.length; + if (len > 0) { + value = {_content_: value}; + for (let i = 0; i < len; i++) { + const attName = n.attributes[i].name; + value[attName] = n.attributes[i].value; + } + } + if (values[localName]) { if (!(values[localName] instanceof Array)) { values[localName] = [values[localName]]; @@ -312,15 +321,6 @@ class GMLBase extends XMLFeature { } else { values[localName] = value; } - - const len = n.attributes.length; - if (len > 0) { - values[localName] = {_content_: values[localName]}; - for (let i = 0; i < len; i++) { - const attName = n.attributes[i].name; - values[localName][attName] = n.attributes[i].value; - } - } } if (!asFeature) { return values; From 7b1c01c50281bd2f881a90b0090b7456a1b24a3b Mon Sep 17 00:00:00 2001 From: Edward Nash Date: Fri, 29 Oct 2021 16:07:13 +0200 Subject: [PATCH 2/2] Add tests parsing multiple complex GML properties --- test/browser/spec/ol/format/gml.test.js | 49 +++++++++++++++++++ .../spec/ol/format/gml/gml32-complex.xml | 49 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 test/browser/spec/ol/format/gml/gml32-complex.xml diff --git a/test/browser/spec/ol/format/gml.test.js b/test/browser/spec/ol/format/gml.test.js index 5aea37a7ea..3c28d0c46e 100644 --- a/test/browser/spec/ol/format/gml.test.js +++ b/test/browser/spec/ol/format/gml.test.js @@ -1840,6 +1840,10 @@ describe('ol.format.GML3', function () { expect(features[0].values_['name']).to.have.length(2); }); + it('parses mutliple simple elements to strings', function () { + expect(features[0].values_['name'][0]).to.be.a('string'); + }); + it('creates nested property', function () { expect( features[0].values_['observationMethod']['CGI_TermValue']['value'][ @@ -2902,4 +2906,49 @@ describe('ol.format.GML32', function () { expect(features[0].get('cdata')).to.be('b'); }); }); + + describe('when parsing multiple complex attributes', function () { + let features; + let gmlFormat; + before(function (done) { + afterLoadText('spec/ol/format/gml/gml32-complex.xml', function (xml) { + try { + gmlFormat = new GML32(); + features = gmlFormat.readFeatures(xml); + } catch (e) { + done(e); + } + done(); + }); + }); + + it('creates 2 features', function () { + expect(features).to.have.length(2); + }); + + it('creates feature with three attributeA properties and two attributeB properties', function () { + expect(features[0].values_['attributeA']).to.have.length(3); + expect(features[0].values_['attributeB']).to.have.length(2); + }); + + it('parses mutliple complex elements to an array of objects', function () { + expect(features[0].values_['attributeA'][0]).to.be.a('object'); + }); + + it('correctly structures multiple elements with attributes', function () { + expect(features[0].values_['attributeA'][0]['xlink:href']).to.be( + 'http://www.example.com/extern/1' + ); + expect(features[0].values_['attributeA'][0]._content_).to.be(undefined); + expect(features[0].values_['attributeA'][1]['xlink:href']).to.be( + 'http://www.example.com/extern/2' + ); + expect(features[0].values_['attributeA'][2]._content_).to.be(undefined); + }); + + it('correctly structures multiple elements with complex content', function () { + expect(features[0].values_['attributeB'][0].Attribute.value).to.be('foo'); + expect(features[0].values_['attributeB'][1].Attribute.value).to.be('bar'); + }); + }); }); diff --git a/test/browser/spec/ol/format/gml/gml32-complex.xml b/test/browser/spec/ol/format/gml/gml32-complex.xml new file mode 100644 index 0000000000..5ed7196a8c --- /dev/null +++ b/test/browser/spec/ol/format/gml/gml32-complex.xml @@ -0,0 +1,49 @@ + + + + + featureA + + + + + + foo + + + + + bar + + + + + 0 0 + + + + + + + featureB + + + + + + foobar + + + + + barfoo + + + + + 1 1 + + + + +