指向由主体解析器解析的深层嵌套对象(表达式)

时间:2019-05-22 03:25:45

标签: javascript node.js

我是一个api开发人员,并且我正在从事的项目现在支持XML和JSON通信。我经常不得不在两者之间进行切换,并且XML通常是深层嵌套的,有时客户会向我们发送不符合我们合同规定的不正确数据。已有模式验证,但有时消息仍然会通过验证,如果不存在字段,它将引发null异常。

类似:

foo.foo2[0].foo3[0].anotherfoo[0].thisAnotherFoo[0]

我曾尝试为访问的每个节点嵌套hasOwnProperty('foo'),但以前从未见过这样的事情,因此必须有一种更好的方法。我知道jQuery不会轰炸您尝试访问DOM中不存在但有Node等效项的属性吗?

1 个答案:

答案 0 :(得分:0)

这是一个递归函数,它遍历给定路径并在遇到不存在的节点时保全(但不抛出)。

const data = {
  foo: {
    foo2: [{
      foo3: [{
          anotherfoo: [{
            thisAnotherFoo: [{
              hello: "hi"
            }]
          }]
        }
      ]
    }]
  }
};

// regex to split the next path chunk from the remaining path
// e.g. 'foo[0].foo2[0].foo3[0]' => ['foo[0]', 'foo2[0].foo3[0]']
const chunk = /([^\.]+)(?:\.(.*))*/;

// regex to test for array access
// e.g. foo[0] => ['foo', '0']
const arrayAccess = /(\w+)(?:\[(\d+)\])*/;

// recursively traverses the given path on data,
// bailing if it encounters a missing path segment
function queryPath(data, path) {

  // consume the current element from path (e.g. 'foo[0]')
  // and capture the remaining path
  const [, current, remaining] = chunk.exec(path);

  // if this path segment uses array access notation,
  // separate the index from the name
  const [, name, index] = arrayAccess.exec(current);

  // get the current node by name (e.g. 'foo')
  const node = data[name];

  // if there's no such node, bail.
  if (node == null) {
    return node;
  }

  // resolve array access if present
  const value = index ? node[parseInt(index)] : node;

  // exit if there's no value here or if
  // we've reached the end of the path
  if (value == null || !remaining) {
    return value;
  }

  // continue with remaining data and path
  return queryPath(value, remaining);
}

// returns {hello: 'hi'}
console.log(queryPath(data, 'foo.foo2[0].foo3[0].anotherfoo[0].thisAnotherFoo[0]'));

// returns undefined
console.log(queryPath(data, 'foo.foo2[0].NONEXISTENTFOO[0].anotherfoo[0].thisAnotherFoo[0]'));