@@ -887,6 +887,7 @@ func (e *Element) readFrom(ri io.Reader, settings ReadSettings) (n int64, err er
887
887
r = newXmlSimpleReader (ri )
888
888
}
889
889
890
+ attrCheck := make (map [xml.Name ]int )
890
891
dec := newDecoder (r , settings )
891
892
892
893
var stack stack [* Element ]
@@ -919,8 +920,19 @@ func (e *Element) readFrom(ri io.Reader, settings ReadSettings) (n int64, err er
919
920
switch t := t .(type ) {
920
921
case xml.StartElement :
921
922
e := newElement (t .Name .Space , t .Name .Local , top )
922
- for _ , a := range t .Attr {
923
- e .createAttr (a .Name .Space , a .Name .Local , a .Value , e , settings .PreserveDuplicateAttrs )
923
+ if settings .PreserveDuplicateAttrs || len (t .Attr ) < 2 {
924
+ for _ , a := range t .Attr {
925
+ e .addAttr (a .Name .Space , a .Name .Local , a .Value )
926
+ }
927
+ } else {
928
+ for _ , a := range t .Attr {
929
+ if i , contains := attrCheck [a .Name ]; contains {
930
+ e .Attr [i ].Value = a .Value
931
+ } else {
932
+ attrCheck [a .Name ] = e .addAttr (a .Name .Space , a .Name .Local , a .Value )
933
+ }
934
+ }
935
+ clear (attrCheck )
924
936
}
925
937
stack .push (e )
926
938
case xml.EndElement :
@@ -1363,28 +1375,29 @@ func (e *Element) addChild(t Token) {
1363
1375
// prefix followed by a colon.
1364
1376
func (e * Element ) CreateAttr (key , value string ) * Attr {
1365
1377
space , skey := spaceDecompose (key )
1366
- return e .createAttr (space , skey , value , e , false )
1367
- }
1368
1378
1369
- // createAttr is a helper function that creates attributes.
1370
- func (e * Element ) createAttr (space , key , value string , parent * Element , preserveDups bool ) * Attr {
1371
- if ! preserveDups {
1372
- for i , a := range e .Attr {
1373
- if space == a .Space && key == a .Key {
1374
- e .Attr [i ].Value = value
1375
- return & e .Attr [i ]
1376
- }
1379
+ for i , a := range e .Attr {
1380
+ if space == a .Space && skey == a .Key {
1381
+ e .Attr [i ].Value = value
1382
+ return & e .Attr [i ]
1377
1383
}
1378
1384
}
1379
1385
1386
+ i := e .addAttr (space , skey , value )
1387
+ return & e .Attr [i ]
1388
+ }
1389
+
1390
+ // addAttr is a helper function that adds an attribute to an element. Returns
1391
+ // the index of the added attribute.
1392
+ func (e * Element ) addAttr (space , key , value string ) int {
1380
1393
a := Attr {
1381
1394
Space : space ,
1382
1395
Key : key ,
1383
1396
Value : value ,
1384
- element : parent ,
1397
+ element : e ,
1385
1398
}
1386
1399
e .Attr = append (e .Attr , a )
1387
- return & e . Attr [ len (e .Attr )- 1 ]
1400
+ return len (e .Attr ) - 1
1388
1401
}
1389
1402
1390
1403
// RemoveAttr removes the first attribute of this element whose key matches
0 commit comments