I have tried using xml2js and fast-xml-parser and get pretty same result from both (although in different formats, but that is not the point here)
This example is from fast-xml-parser
I have this XML:
<test version="1"> <case tm-reference="reference-to-test-management-test id"> <description>Test description ..</description> <steps> <platform type="appium" navigate-to="x in list-of-values"> <expect fan="AUTO"/> </platform> <tstat> <set mode="HEAT" fan="AUTO" RT="70F" SP="70F"/> </tstat> <!-- value in milliseconds --> <wait for="500"/> <platform type="appium"> <expect fan="AUTO"/> </platform> <!-- value in milliseconds --> <wait for="500"/> <tstat> <set mode="HEAT" fan="AUTO" RT="70F" SP="70F"/> <wait for="500"/> <expect led-g="ON" led-y="ON"/> <wait for="500"/> <expect led-g="ON" led-y="ON"/> </tstat> </steps> </case> </test> parsing it like this:
import parser from "fast-xml-parser" const result = parser.parse(this.xml, { parseAttributeValue: true, ignoreAttributes: false, allowBooleanAttributes: true, attributeNamePrefix: "" }) console.log(JSON.stringify(result, null, 2)); doing this result in this:
{ "test": { "version": 1, "case": { "tm-reference": "some reference ID", "description": "Test description ..", "steps": { "platform": [ { "type": "appium", "navigate-to": "x in list-of-values", "expect": { "fan": "AUTO" } }, { "type": "appium", "expect": { "fan": "AUTO" } } ], "tstat": [ { "id": "", "set": { "mode": "HEAT", "fan": "AUTO", "RT": "70F", "SP": "70F" } }, { "set": { "mode": "HEAT", "fan": "AUTO", "RT": "70F", "SP": "70F" }, "wait": [ { "for": 500 }, { "for": 500 } ], "expect": [ { "led-g": "ON", "led-y": "ON" }, { "led-g": "ON", "led-y": "ON" } ] } ], "wait": [ { "for": 500 }, { "for": 500 } ] } } } } Notice how the repeated tags for example platform, tstat and wait have been combined together into an array and lost the order of actual their placements in xml file. I am looking for a way to actually preserve the order and repetition of tags. somehow I get the array of steps(objects) with each tag's information in the same order as in xml file
EDIT: Adding expected output I'm expecting if not exactly but something similar where order is preserved for each tag
{ "test": { "version": 1, "children": [ { "case": { "tm-reference": "some reference ID", "description": "Test description ..", "steps": { "children": [ { "platform": { "type": "appium", "navigate-to": "x in list-of-values", "children": [ { "expect": { "fan": "AUTO" } } ] } }, { "tstat": { "id": "", "children": [ { "set": { "mode": "HEAT", "fan": "AUTO", "RT": "70F", "SP": "70F" } } ] } }, { "wait": { "for": 500, "children": [] } }, { "platform": { "type": "appium", "children": [ { "expect": { "fan": "AUTO" } } ] } }, { "wait": { "for": 500, "children": [] } }, { "tstat": { "children": [ { "set": { "mode": "HEAT", "fan": "AUTO", "RT": "70F", "SP": "70F" } }, { "wait": { "for": 500 } }, { "expect": { "led-g": "ON", "led-y": "ON" } }, { "wait": { "for": 500 } }, { "expect": { "led-g": "ON", "led-y": "ON" } } ] } } ] } } } ] } } EDIT 2:
Created an issue on GitHub repo, follow here
1 Answer
You want your steps element's content to be represented in JSON as an array, not an object, because JavaScript object properties are unordered and may not repeat names.
In fast-xml-parser, you may be able to achieve this via the arrayMode option:
4arrayMode : When
false, a tag with single occurrence is parsed as an object but as an array in case of multiple occurences. Whentrue, a tag will be parsed as an array always excluding leaf nodes. Whenstrict, all the tags will be parsed as array only. When instance ofRegEx, only tags will be parsed as array that match the regex. Whenfunctiona tag name is passed to the callback that can be checked.