簡體   English   中英

我們如何扁平化使用 fast-xml-parser 解析的 XML

[英]How can we flatten XML parsed with fast-xml-parser

繼承了一個需要維護的 Node.js 應用程序,這不是我的強項。

我們正在使用 fast-xml-parser 解析 XML,它對我們的大多數輸入都非常有效。 然而,我們有一些輸入是額外的級別,我們需要將輸出展平到相同的級別。

輸入:其中價格值是額外的深度

<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])

想法? 謝謝

在最新版本的 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"
}

但是,標簽名稱不能更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM