Skip to content

Commit

Permalink
feat(developer): fast-xml-parser: fix for ldml empty attributes
Browse files Browse the repository at this point in the history
- because of the form to="" in ldml, we need to distinguish attributes and sub-elements in the ldml xml parsing
- use an attributePrefix, and fixup the object tree afterwards

Fixes: #12208
  • Loading branch information
srl295 committed Oct 3, 2024
1 parent 6c0d240 commit 03a24a1
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 14 deletions.
42 changes: 28 additions & 14 deletions developer/src/common/web/utils/src/xml-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type KemanXMLOptionsBag = {
const PARSER_OPTIONS: KemanXMLOptionsBag = {
'keyboard3': {
ignoreAttributes: false, // We'd like attributes, please
attributeNamePrefix: '', // to avoid '@_' prefixes
attributeNamePrefix: '@__', // We'll use this to convert attributes to strings and subobjects to arrays, when empty.
trimValues: false, // preserve spaces, but:
htmlEntities: true,
tagValueProcessor: (tagName: string, tagValue: string /*, jPath, hasAttributes, isLeafNode*/) => {
Expand Down Expand Up @@ -133,19 +133,35 @@ export class KeymanXMLReader {
}
}

/** replace any empty string "" with an empty object {} */
/**
* Requires attribute prefix @__ (double underscore)
* For attributes, just remove @__ and continue.
* For objects, replace any empty string "" with an empty object {} */
private static fixupEmptyStringToEmptyObject(data: any) : any {
if (data === "") {
// this is the core feature here.
return {};
} else if (typeof data === 'object') {
if (typeof data === 'object') {
// For arrays of objects, we map "" to {}
// "" means an empty object
if (Array.isArray(data)) {
return data.map(v => KeymanXMLReader.fixupEmptyStringToEmptyObject(v));
return data.map(v => {
if (v === '') {
return {};
} else {
return KeymanXMLReader.fixupEmptyStringToEmptyObject(v);
}
});
}
// object
const e : any = [];
// otherwise: remove @__ for attributes, remap objects
const e: any = [];
Object.entries(data).forEach(([k, v]) => {
e.push([k, KeymanXMLReader.fixupEmptyStringToEmptyObject(v)]);
if (k.startsWith('@__')) {
e.push([k.substring(3), KeymanXMLReader.fixupEmptyStringToEmptyObject(v)]);
} else {
if (v === '') {
e.push([k, {}]);
} else {
e.push([k, KeymanXMLReader.fixupEmptyStringToEmptyObject(v)]);
}
}
});
return Object.fromEntries(e);
} else {
Expand Down Expand Up @@ -217,11 +233,9 @@ export class KeymanXMLReader {
let result = parser.parse(data, true);
if (PARSER_OPTIONS[this.type].attributeNamePrefix === '$') {
result = KeymanXMLReader.fixupDollarAttributes(result);
}
if (this.type === 'keyboard3') {
} else if (PARSER_OPTIONS[this.type].attributeNamePrefix === '@__') {
result = KeymanXMLReader.fixupEmptyStringToEmptyObject(result);
}
if (PARSER_OPTIONS[this.type].preserveOrder) {
} else if (PARSER_OPTIONS[this.type].preserveOrder) {
result = KeymanXMLReader.fixupPreserveOrder(result);
}
delete result['?xml'];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>

<keyboard3 conformsTo="45" xmlns="https://schemas.unicode.org/cldr/45/keyboard3" locale="mt" >
<info name="fail-matches-nothing"/>

<keys />

<transforms type="simple">
<transformGroup>
<transform from=""/>
</transformGroup>
</transforms>
</keyboard3>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"keyboard3": {
"conformsTo": "45",
"xmlns": "https://schemas.unicode.org/cldr/45/keyboard3",
"locale": "mt",
"info": {
"name": "fail-matches-nothing"
},
"keys": {},
"transforms": {
"type": "simple",
"transformGroup": {
"transform": {
"from": ""
}
}
}
}
}
1 change: 1 addition & 0 deletions developer/src/common/web/utils/test/test-xml-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const read_cases: Case[] = [
'k_020_fr.xml',
'strs_invalid-illegal.xml',
'tran_fail-empty.xml',
'tran_fail-matches-nothing-1.xml',
],
}, {
type: 'keyboardTest3',
Expand Down

0 comments on commit 03a24a1

Please sign in to comment.