Рубрики
Без рубрики

Преобразование XML в JSON, используя рекурсию

Преобразование XML в JSON в JavaScript не должно быть сложно. Вот как это сделать.

Автор оригинала: Nitin Patel.

На днях я работал над приложением, которое необходимо для получения данных от третьей сторонней API отдыха, и что произошло следующее, – это то, что один из худших кошмаров разработчика JavaScript.

Сервер отправил ответ на обратную ответницу.

Итак, я придумал способ легко преобразовать XML в объект JavaScript. Вот пример данных, которые я пытался прочитать.

Имейте в виду, что этот код использует Webapis, поэтому он не доступен в Server Side JavaScript, как Nodejs. Это отлично работает для приложений для передних конечностей, таких как реагирование или угловые.

Формат XML, как правило, что-то подобное:


    Some title
    some description 
    
        1
        some author name
    
    nice book
    this book sucks
    amazing work

Я хочу, чтобы вывести немного посмотреть что-то вроде этого:

{
  "book": {
    "title": "Some title",
    "description": "some description",
    "author": { "id": "1", "name": "some author name" },
    "review": ["nice book", "this book sucks", "amazing work"]
  }
}

Поскольку XML имеет много вложенных тегов, эта проблема является идеальным примером практического применения рекурсии.

Прежде чем начать кодировать, нам нужно понять что-то названное Domparser Веб-API.

Согласно документации MDN,

Domparser Интерфейс предоставляет возможность анализировать XML или HTML Исходный код из строки в дереве DOM.

Простые слова, это преобразует строку XML в дерево DOM. Вот как это работает.

Позвольте сказать, что у нас есть какой-то XML, сохраненный в строке, strxml. Мы можем разбирать данные в нем как дерево DOM, как это:

let strxml = `Some title
some description 

    1
    some author name

nice book
this book sucks
amazing work
`;

const parser = new DOMParser();  // initialize dom parser
const srcDOM = parser.parseFromString(strxml, "application/xml");  // convert dom string to dom tree. 

// Now we can call DOM methods like GetElementById, etc. on scrDOM. 

Теперь, когда у нас есть основные основы. Давайте начнем писать псевдо код.

Initialize variable jsonResult is empty object. 
If scrDOM has no children nodes:
    return innerHTML of the DOM. // This is our base case.

For each childNode in children nodes:
    Check if childNode has siblings of same name. 
    If it has no siblings of same name: 
        set childnode name as key whose value is json of the child node. (we're calling the function recursively.)
    If it has no siblings of same name
        set childnode name as key whose value is an empty array, every child whose name is same as this pushed into this array.
return jsonResult

Вот код JavaScript:

/**
 * This function coverts a DOM Tree into JavaScript Object. 
 * @param srcDOM: DOM Tree to be converted. 
 */
function xml2json(srcDOM) {
  let children = [...srcDOM.children];
  
  // base case for recursion. 
  if (!children.length) {
    return srcDOM.innerHTML
  }
  
  // initializing object to be returned. 
  let jsonResult = {};
  
  for (let child of children) {
    
    // checking is child has siblings of same name. 
    let childIsArray = children.filter(eachChild => eachChild.nodeName === child.nodeName).length > 1;

    // if child is array, save the values as array, else as strings. 
    if (childIsArray) {
      if (jsonResult[child.nodeName] === undefined) {
        jsonResult[child.nodeName] = [xml2json(child)];
      } else {
        jsonResult[child.nodeName].push(xml2json(child));
      }
    } else {
      jsonResult[child.nodeName] = xml2json(child);
    }
  }
  
  return jsonResult;
}

// testing the function
let xmlstr = `Some title
some description 

    1
    some author name

nice book
this book sucks
amazing work
`;

// converting to DOM Tree
const parser = new DOMParser();
const srcDOM = parser.parseFromString(xmlstr, "application/xml");

// Converting DOM Tree To JSON. 
console.log(xml2json(srcDOM));

/** The output will be
{
  "book": {
    "title": "Some title",
    "description": "some description",
    "author": { "id": "1", "name": "some author name" },
    "review": ["nice book", "this book sucks", "amazing work"]
  }
}
*/

Это основной алгоритм/код для преобразования строки XML в объект JSON. Поскольку он использует рекурсию, он может очень глубоко в дереве DOM и разбирать каждый элемент.

Это работает для большинства случаев. Вы можете изменить этот алгоритм в соответствии с вашими потребностями или требованиями.