Как мы можем сгладить XML, проанализированный с помощью fast-xml-parser
Унаследовал приложение Node.js, которое требует некоторого обслуживания и не является моей сильной стороной.
Мы анализируем XML с помощью fast-xml-parser, который очень хорошо работает с большинством наших входных данных. Однако у нас есть некоторые входные данные, которые находятся на дополнительном уровне, и нам нужно выровнять выход, чтобы все они были одного уровня.
Входные данные: где значение цены является глубиной дополнительного уровня.
<products capture-installed="true">
<script/>
<script/>
<script/>
<product>
<pid>8</pid>
<modelno>6273033</modelno>
<name>
<![CDATA[ Big Red Truck ]]>
</name>
<category>
<![CDATA[ Toys]]>
</category>
<currency>USD</currency>
<price>
<actualprice>19.20</actualprice>
</price>
</product>
Когда мы сглаживаем его существующим кодом, мы получаем:
"product": {
"pid": "8",
"modelno": "6273033",
"name": "Big Red Truck",
"category": "Toys",
"currency": "USD",
"price": {
"actualprice": "19.20"
}
Но нам нужно что-то вроде:
"product": {
"pid": "8",
"modelno": "6273033",
"name": "Big Red Truck",
"category": "Toys",
"currency": "USD",
"price-actualprice": "19.20"
}
Текущий Кодекс:
const parse = require("fast-xml-parser");
const options = {
ignoreAttributes : true,
ignoreNameSpace : false,
parseNodeValue : false,
tagValueProcessor : a => {
if(Array.isArray(a)){
return a.join(',');
}
return a;
}
};
const flatten = (data) => {
return data.map(row => {
const fieldNames = Object.keys(row);
for (const fieldName of fieldNames) {
if(Array.isArray(row[fieldName])){
row[fieldName] = row[fieldName].join(',');
}
if(typeof row[fieldName] === 'object'){
row[fieldName] = JSON.stringify(row[fieldName]);
}
}
return row;
});
};
function findTheArray(o) {
if(Array.isArray(o)){
return o;
}
var result, p;
for (p in o) {
if( o.hasOwnProperty(p) && typeof o[p] === 'object' ) {
result = findTheArray(o[p]);
if(result){
return result;
}
}
}
return result;
}
module.exports = function parseData(data) {
return new Promise((resolve, reject) => {
try {
const isValid = parse.validate(data);
if (isValid === true) {
const pData = parse.parse(data, options);
const array = findTheArray(pData);
if(array){
resolve(flatten(array));
} else {
reject('Can\'t find any goodies!');
}
} else {
reject(isValid.err);
}
} catch (err) {
reject(err);
}
});
};
Я работал над этой областью кода, но безуспешно:
if(typeof row[fieldName] === 'object'){
row[fieldName] = JSON.stringify(row[fieldName])
Идеи? Спасибо
1 ответ
В последней версии FXP вы можете сделать это так;
const options = {
ignoreAttributes: true,
stopNodes: [
"products.product.price"
],
tagValueProcessor: (tagName, tagValue, jPath, hasAttributes, isLeafNode) => {
if (jPath === 'products.product.price') {
return /([0-9]+\.[0-9]+)/.exec(tagValue)[1]
}
},
// preserveOrder: true,
};
const parser = new XMLParser(options);
let result = parser.parse(XMLdata);
Выход
"product": {
"pid": "8",
"modelno": "6273033",
"name": "Big Red Truck",
"category": "Toys",
"currency": "USD",
"price": "19.20"
}
Однако имя тега изменить нельзя.