-
-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maintain ordering #104
Comments
Did you try the https://oozcitak.github.io/xmlbuilder2/serialization.html#js-object-and-map-serializers |
Yeh, but if you have a node that has children of different element types interspersed, it groups by the element type. Which loses ordering. |
Can you create a test case to reproduce? |
The structure of the object seems to change depending on whether there are intersperesed children of different types or not. In order to use the serialized object, I need a consistent structure.
Test case:// @ts-nocheck
import $$ from '../TestHelpers'
describe('Replicate issue', () => {
test('#104 - Maintain ordering for interspersed children of different element type', () => {
const xmlA = $$.t`
<?xml version="1.0"?>
<root>
<person age="35"/>
<ele>simple element</ele>
<person age="30"/>
</root>
`
const xmlB = $$.t`
<?xml version="1.0"?>
<root>
<person age="35"/>
<person age="30"/>
<ele>simple element</ele>
</root>
`
const expectedObjA = {
'root': {
'#': [
{
'person': {
'@age': '35'
}
},
{
'ele': 'simple element'
},
{
'person': {
'@age': '30'
}
}
]
}
}
const expectedObjB = {
'root': {
'#': [
{
'person': {
'@age': '35'
}
},
{
'person': {
'@age': '30'
}
},
{
'ele': 'simple element'
},
]
}
}
const verbose = true
const group = false
const format = 'map'
const docA = $$.create(xmlA)
const docB = $$.create(xmlB)
const objA = docA.end({format, verbose, group})
const objB = docB.end({format, verbose, group})
console.log(JSON.stringify(toObject(objA), null, 2))
console.log(JSON.stringify(toObject(objB), null, 2))
expect(toObject(objA)).toEqual(expectedObjA)
expect(toObject(objB)).toEqual(expectedObjB)
const xmlFromObjA = $$.create(objA).end({prettyPrint: true})
const xmlFromObjB = $$.create(objB).end({prettyPrint: true})
expect(xmlFromObjA).toEqual(xmlA)
expect(xmlFromObjB).toEqual(xmlB)
})
})
const toObject = (map = new Map) => {
if (!(map instanceof Map)) return map
return Object.fromEntries(Array.from(map.entries(), ([k, v]) => {
if (v instanceof Array) {
return [k, v.map(toObject)]
} else if (v instanceof Map) {
return [k, toObject(v)]
} else {
return [k, v]
}
}))
}
|
So actually, it doesn't lose ordering...but the serialized object is inconsistent, making it difficult to traverse.
I need to work with a JSON object because I want to modify things, and then diff, which is more difficult with the DOM. I think |
@oozcitak Hello! Any update on this? We can't trust that object keys are going to remain in the same order, children need to be contained inside arrays. |
Is your feature request related to a problem? Please describe.
In order to do
xml -> json -> xml
without any re-ordering, children must always be in an array, not grouped by their tag type.Describe the solution you'd like
Like
xml-js
does with{compact: false}
. An option where all children are always an array.Describe alternatives you've considered
Manipulating the DOM instead which maintains ordering.
The text was updated successfully, but these errors were encountered: