Skip to content

Commit

Permalink
feat(developer): fast-xml-parser reader:
Browse files Browse the repository at this point in the history
- WIP preserveorder

Fixes: #12208
  • Loading branch information
srl295 committed Oct 2, 2024
1 parent 55473bf commit b69f636
Showing 1 changed file with 54 additions and 1 deletion.
55 changes: 54 additions & 1 deletion developer/src/common/web/utils/src/xml-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const PARSER_OPTIONS: KemanXMLOptionsBag = {
htmlEntities: true,
ignoreAttributes: false, // We'd like attributes, please
attributeNamePrefix: '', // avoid @_
preserveOrder: true, // Gives us a 'special' format - see boxTestDataArrays() below
preserveOrder: true, // Gives us a 'special' format
},
'kps': {
ignorePiTags: true,
Expand Down Expand Up @@ -151,6 +151,56 @@ export class KeymanXMLReader {
}
}

/**
* Replace:
* ```json
* [ { "info": [], ":@": { "abc": "def" } }]
* ```
* with:
* ```json
* [{"$": { "abc": "def" }, "#name": "info" }]
* ```
* see https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/docs/v4/2.XMLparseOptions.md#preserveorder
* @param data input data
*/
private static fixupPreserveOrder(data: any): any {

// we need to extract the root name specially
if (!Array.isArray(data)) {
throw Error(`Internal Error: XML parser preserveOrder did not yield an array.`);
}
if (data.length !== 1) {
// we ignore comments, so should only have one element
throw Error(`Internal Error: XML parser preserveOrder did not yield an array of size 1.`);
}
// the root element is special, we copy it into a property
const rootElement = KeymanXMLReader.fixupPreserveOrderObject(data[0]);
const rootElementName = rootElement['#name'];
const out: any = {};
out[rootElementName] = rootElement;
return out;
}

/** takes an 'object' with a property `:@` containing attrs, and one other property with the object name */
private static fixupPreserveOrderObject(data: any): any {
const attrs = data[':@'];
const mainEntry : any = Object.entries(data).filter(([k,v]) => k !== ':@');
const [elementName, subItems] = mainEntry[0];
const out : any = {};
if ( attrs ) {
out['$'] = attrs;
}
if (!elementName) {
console.dir({data});
throw Error(`could not find elementName`);
}
out['#name'] = elementName;
if (subItems && subItems.length) {
out['$$'] = subItems.map((subObject: any) => KeymanXMLReader.fixupPreserveOrderObject(subObject));
}
return out;
}

public parse(data: string): any {
const parser = this.parser();
let result = parser.parse(data);
Expand All @@ -160,6 +210,9 @@ export class KeymanXMLReader {
if (this.type === 'keyboard3') {
result = KeymanXMLReader.fixupEmptyStringToEmptyObject(result);
}
if (PARSER_OPTIONS[this.type].preserveOrder) {
result = KeymanXMLReader.fixupPreserveOrder(result);
}
delete result['?xml'];
return result;
}
Expand Down

0 comments on commit b69f636

Please sign in to comment.