从JSON字符串中提取嵌套的<a>元素

时间:2019-06-30 20:25:00

标签: javascript arrays node.js recursion

我试图在JSON字符串中找到所有“ a”键,并将它们保存在数组中。由于它们可能嵌套在不同的级别,因此我使用递归遍历每个键的子级,以详尽列出所有“ a”键。但是,我无法绕着递归子节点并将找到的所有“ a”键附加到返回的数组。任何帮助,我们将不胜感激。

用于遍历JSON字符串的函数:

searchForKeys = (keyValue, obj) => {

  let arrayOfKeys = [];

  if (obj instanceof Array) {
    obj.forEach((item, index) => {

     if(typeof(item) === 'object' && Object.keys(item)[index] === keyValue) {
        console.log('pushing found item to return array');
        arrayOfKeys.push(...item);
        console.log(arrayOfKeys);
     } 
    });
  }
  else if (typeof(obj) === 'object') {
    if (Object.keys(obj).length > 0) {
      let itemName;
      for(let i = 0; i < Object.keys(obj).length; i++) {
        itemName = Object.keys(obj)[i];
        if (itemName === keyValue) {
          console.log('pushing found item to return array');
          arrayOfKeys.push(obj[itemName]);
        }
      }
      console.log('arrayOfKeys.length:', arrayOfKeys.length);
      arrayOfKeys.push(searchForKeys(keyValue, obj[itemName]));
  }
  return arrayOfKeys;
  }
};

let returnedArray = searchForKeys("a", dummyJSON);

console.log("array content:\n", [...returnedArray]); 
console.log("array length", returnedArray.length);

返回的预期结果是Array,其中包含JSON对象中的所有四个“ a”键。

源数据:

const dummyJSON = {
  "a": {
    "@attributes": {
      "href": "/URL/2021.html?q=link+value",
      "title": "Lautsprecher",
      "class": "catfilter-list-link",
      "data-gtm-event": "filter.click",
      "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
      "data-metric-click": "mainsearch-catfilter-click"
    },
    "#text": "Lautsprecher"
  },
  "ul": {
    "@attributes": {
      "class": "catfilter-list"
    },
    "#text": [],
    "li": [
      {
        "@attributes": {
          "class": "catfilter-list-item"
        },
        "#text": [
          "",
          ""
        ],
        "a": {
          "@attributes": {
            "href": "/URL/8412.html?q=link+value",
            "title": "Handy-Ladegeräte",
            "class": "catfilter-list-link",
            "data-gtm-event": "filter.click",
            "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
            "data-metric-click": "mainsearch-catfilter-click"
          },
          "#text": "Handy-Ladegeräte"
        }
      },
      {
        "@attributes": {
          "class": "catfilter-list-item"
        },
        "#text": [
          "",
          ""
        ],
        "a": {
          "@attributes": {
            "href": "/URL/26136.html?q=link+value",
            "title": "Kabellose Ladegeräte",
            "class": "catfilter-list-link",
            "data-gtm-event": "filter.click",
            "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
            "data-metric-click": "mainsearch-catfilter-click"
          },
          "#text": "Kabellose Ladegeräte"
        }
      },
      {
        "@attributes": {
          "class": "catfilter-list-item"
        },
        "a": {
          "@attributes": {
            "href": "/URL/2021.html?q=link+value",
            "title": "Lautsprecher",
            "class": "catfilter-list-link",
            "data-gtm-event": "filter.click",
            "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
            "data-metric-click": "mainsearch-catfilter-click"
          },
          "#text": "Lautsprecher"
        },
        "#text": [
          "",
          ""
        ],
        "a": {
          "@attributes": {
            "href": "/URL/2021.html?q=link+value",
            "title": "Lautsprecher",
            "class": "catfilter-list-link",
            "data-gtm-event": "filter.click",
            "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
            "data-metric-click": "mainsearch-catfilter-click"
          },
          "#text": "Lautsprecher"
        }
      }
    ]
  }
};

3 个答案:

答案 0 :(得分:1)

对于JSON字符串,可以使用JSON.parse reviver parameter

var arr = [], json = JSON.stringify({"a":{"@attributes":{"href":"/URL/2021.html?q=link+value","title":"Lautsprecher","class":"catfilter-list-link","data-gtm-event":"filter.click","data-gtm-payload":"{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}","data-metric-click":"mainsearch-catfilter-click"},"#text":"Lautsprecher"},"ul":{"@attributes":{"class":"catfilter-list"},"#text":[],"li":[{"@attributes":{"class":"catfilter-list-item"},"#text":["",""],"a":{"@attributes":{"href":"/URL/8412.html?q=link+value","title":"Handy-Ladegeräte","class":"catfilter-list-link","data-gtm-event":"filter.click","data-gtm-payload":"{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}","data-metric-click":"mainsearch-catfilter-click"},"#text":"Handy-Ladegeräte"}},{"@attributes":{"class":"catfilter-list-item"},"#text":["",""],"a":{"@attributes":{"href":"/URL/26136.html?q=link+value","title":"Kabellose Ladegeräte","class":"catfilter-list-link","data-gtm-event":"filter.click","data-gtm-payload":"{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}","data-metric-click":"mainsearch-catfilter-click"},"#text":"Kabellose Ladegeräte"}},{"@attributes":{"class":"catfilter-list-item"},"a":{"@attributes":{"href":"/URL/2021.html?q=link+value","title":"Lautsprecher","class":"catfilter-list-link","data-gtm-event":"filter.click","data-gtm-payload":"{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}","data-metric-click":"mainsearch-catfilter-click"},"#text":"Lautsprecher"},"#text":["",""],"a":{"@attributes":{"href":"/URL/2021.html?q=link+value","title":"Lautsprecher","class":"catfilter-list-link","data-gtm-event":"filter.click","data-gtm-payload":"{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}","data-metric-click":"mainsearch-catfilter-click"},"#text":"Lautsprecher"}}]}})

JSON.parse(json, (key, val) => key == 'a' ? arr.push(val) : val)

console.log( arr )

答案 1 :(得分:1)

这是使用Array.prototype.flatMap的一种可能方法-

const valuesForProp = (q = "", o = {}) =>
  Object (o) === o
    ? Object
        .entries (o)
        .flatMap
          ( ([ k, v ]) =>
              k === q
                ? [ v, ...valuesForProp (q, v) ]
                : valuesForProp (q, v)
          )
    : []

我们使用简化的data并测试输出-

const data =
  { a: { b: 0, c: { a: 1 } }
  , b: [ { a: 2 } ]
  , c: { d: 0 }
  , e: { f: { g: { h: { a: 3 } } } }
  , i: { j: [ { a: 4 }, { a: 5 } ] }
  }


valuesForProp ("a", data)
// => [ { b: 0, c: { a: 1 } }, 1, 2, 3, 4, 5 ]

valuesForProp ("b", data)
// => [ 0, [ { a: 2 } ] ]

valuesForProp ("c", data)
// => [ { a: 1 }, { d: 0 } ]

valuesForProp ("z", data)
// => []

展开以下代码段,以在您自己的浏览器中验证结果-

const data =
  { a: { b: 0, c: { a: 1 } }
  , b: [ { a: 2 } ]
  , c: { d: 0 }
  , e: { f: { g: { h: { a: 3 } } } }
  , i: { j: [ { a: 4 }, { a: 5 } ] }
  }

const valuesForProp = (q = "", o = {}) =>
  Object (o) === o
    ? Object
        .entries (o)
        .flatMap
          ( ([ k, v ]) =>
              k === q
                ? [ v, ...valuesForProp (q, v) ]
                : valuesForProp (q, v)
          )
    : []

console .log (valuesForProp ("a", data))
// => [ { b: 0, c: { a: 1 } }, 1, 2, 3, 4, 5 ]

console .log (valuesForProp ("b", data))
// => [ 0, [ { a: 2 } ] ]

console .log (valuesForProp ("c", data))
// => [ { a: 1 }, { d: 0 } ]

console .log (valuesForProp ("z", data))
// => []

答案 2 :(得分:0)

查询JSON子节的最简单方法是JSONPath expressions,要解决此任务,只需应用 $ .. a 表达式以递归选择所有必需的后代(请参阅{{3} }。

var JSONPath = require('JSONPath');

JSONPath({
  json: dummyJSON, 
  path: '$..a',
  flatten: true, 
  callback: (result) => {
    console.log(result);
}});

源数据:

const dummyJSON = {
  "a": {
    "@attributes": {
      "href": "/URL/2021.html?q=link+value",
      "title": "Lautsprecher",
      "class": "catfilter-list-link",
      "data-gtm-event": "filter.click",
      "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
      "data-metric-click": "mainsearch-catfilter-click"
    },
    "#text": "Lautsprecher"
  },
  "ul": {
    "@attributes": {
      "class": "catfilter-list"
    },
    "#text": [],
    "li": [
      {
        "@attributes": {
          "class": "catfilter-list-item"
        },
        "#text": [
          "",
          ""
        ],
        "a": {
          "@attributes": {
            "href": "/URL/8412.html?q=link+value",
            "title": "Handy-Ladegeräte",
            "class": "catfilter-list-link",
            "data-gtm-event": "filter.click",
            "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
            "data-metric-click": "mainsearch-catfilter-click"
          },
          "#text": "Handy-Ladegeräte"
        }
      },
      {
        "@attributes": {
          "class": "catfilter-list-item"
        },
        "#text": [
          "",
          ""
        ],
        "a": {
          "@attributes": {
            "href": "/URL/26136.html?q=link+value",
            "title": "Kabellose Ladegeräte",
            "class": "catfilter-list-link",
            "data-gtm-event": "filter.click",
            "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
            "data-metric-click": "mainsearch-catfilter-click"
          },
          "#text": "Kabellose Ladegeräte"
        }
      },
      {
        "@attributes": {
          "class": "catfilter-list-item"
        },
        "a": {
          "@attributes": {
            "href": "/URL/2021.html?q=link+value",
            "title": "Lautsprecher",
            "class": "catfilter-list-link",
            "data-gtm-event": "filter.click",
            "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
            "data-metric-click": "mainsearch-catfilter-click"
          },
          "#text": "Lautsprecher"
        },
        "#text": [
          "",
          ""
        ],
        "a": {
          "@attributes": {
            "href": "/URL/2021.html?q=link+value",
            "title": "Lautsprecher",
            "class": "catfilter-list-link",
            "data-gtm-event": "filter.click",
            "data-gtm-payload": "{\"event_category\":\"mainsearch\",\"event_action\":\"quickfilter.click\",\"event_label\":\"quickfilter\",\"position\":\"1\",\"location\":\"headline\"}",
            "data-metric-click": "mainsearch-catfilter-click"
          },
          "#text": "Lautsprecher"
        }
      }
    ]
  }
};