in src/main.ts [461:529]
static parse(xlfString: string): Promise<ParsedXLF[]> {
const getValue = function (this: void, target: any): string | undefined {
if (typeof target === 'string') {
return target;
}
if (typeof target._ === 'string') {
return target._;
}
if (Array.isArray(target) && target.length === 1) {
const item = target[0];
if (typeof item === 'string') {
return item;
}
if (typeof item._ === 'string') {
return item._;
}
return target[0]._;
}
return undefined;
};
return new Promise((resolve, reject) => {
const parser = new xml2js.Parser();
const files: { messages: Map<string>, originalFilePath: string, language: string }[] = [];
parser.parseString(xlfString, function (err: any, result: any) {
if (err) {
reject(new Error(`Failed to parse XLIFF string. ${err}`));
}
const fileNodes: any[] = result['xliff']['file'];
if (!fileNodes) {
reject(new Error('XLIFF file does not contain "xliff" or "file" node(s) required for parsing.'));
}
fileNodes.forEach((file) => {
const originalFilePath = file.$.original;
if (!originalFilePath) {
reject(new Error('XLIFF file node does not contain original attribute to determine the original location of the resource file.'));
}
const language = file.$['target-language'].toLowerCase();
if (!language) {
reject(new Error('XLIFF file node does not contain target-language attribute to determine translated language.'));
}
const messages: Map<string> = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach((unit: any) => {
const key = unit.$.id;
if (!unit.target) {
return; // No translation available
}
const val = getValue(unit.target);
if (key && val) {
messages[key] = decodeEntities(val);
} else {
reject(new Error('XLIFF file does not contain full localization data. ID or target translation for one of the trans-unit nodes is not present.'));
}
});
files.push({ messages: messages, originalFilePath: originalFilePath, language: language });
}
});
resolve(files);
});
});
}