javascript - 使用 Javascript 搜索具有精确标签的 JSON

标签 javascript jquery json xpath

我有以下 JSON,其中通过选择过滤器来执行搜索:

{
  "Books": [
     {
        "title": "Book 1",
        "binding": "paperback",
        "category": "pop",
        "language": "english",
        "author": "male"
     },
     {
        "title": "Book 2",
        "binding": "hardcover",
        "category": "pop rock,electro pop",
        "language": "french",
        "author": "female"
     },
     {
        "title": "Book 3",
        "binding": "audiobook",
        "category": "soft rock",
        "language": "german",
        "author": "male,female"
     },
     {
        "title": "Book 4",
        "binding": "boxed set",
        "category": "rock,classic rock",
        "language": "english",
        "author": "female,male"
     },
     {
        "title": "Book 5",
        "binding": "paperback",
        "category": "electro pop,rock,classic rock",
        "language": "french",
        "author": "male/female"
     },
     {
        "title": "Book 6",
        "binding": "paperback",
        "category": "rock",
        "language": "french",
        "author": "male"
     }
  ]
}

可用的过滤器有

Binding
  -Paperback
  -Hardcover
  -Audiobook
  -Boxed Set

Category
  -Classic Rock
  -Pop
  -Pop Rock
  -Electro Pop
  -Soft Rock
  -Rock

Language
  -German
  -English
  -French

Author
  -Male
  -Female
  -Male/Female

我正在使用defiant.js从 JSON 中搜索。当我使用以下查询时:

var thequery = [];
for (var i in searchTags) {
    for (var j = 0; j < searchTags[i].length; j++) {
        thequery.push('contains(' + i + ' ,"' + searchTags[i][j] + '")');   
    }
}
var thequeryString = thequery.join(' and ');
console.log('//*[' + firstqueryString + ']');
return '//*[' + thequeryString + ']';

因此,当我第一次单击绑定(bind)过滤器时,我得到的查询是 //*[contains(binding ,"paperback")] ,当我第二次单击时,返回的查询是 >//*[contains(binding ,"paperback") 和 contains(binding ,"boxed set")] 然后正确过滤结果。

但现在的问题是,如果我想获取流派 pop 的书籍,然后使用查询 //*[contains(category ,"rock")]我明白

  1. 第 2 册
  2. 第 3 册
  3. 第 4 册
  4. 第 5 册
  5. 第 6 册

但实际上只有第4册第5册第6册摇滚类别。

我尝试的另一个查询是:

var thequery = [];
for (var i in searchTags) {
    for (var j = 0; j < searchTags[i].length; j++) {
        if(i == 'author' || i == 'category'){ 
            thequery.push(i + '[contains(.,"' + searchTags[i][j] + ',")] or ' + i + '[contains(.,",' + searchTags[i][j] + '")] or ' + i + '="' + searchTags[i][j] + '"');
        }else{
            thequery.push('contains(' + i + ' ,"' + searchTags[i][j] + '")'); 
        }
    }
}
var thequeryString = thequery.join(' and ');
console.log('//*[' + firstqueryString + ']');
return '//*[' + thequeryString + ']';

我得到的查询是//*[category[contains(.,"rock,")]或category[contains(.,", rock")]或category ="rock"]返回:

  1. 第 2 册
  2. 第 4 册
  3. 第 5 册
  4. 第 6 册

我能到达的最近的地方只有这里。

所以,总结一下我有两个问题:

  1. 如何使用我单击的确切过滤器来过滤图书。例如。如果我单击“Rock”,则仅应返回包含“rock”类别的书籍。
  2. 如果我使用//*[category[contains(.,"rock,")]或category[contains(.,", rock")]或category ="rock"]并且将其与主 thequeryStringand 连接起来,它不会过滤掉正确的结果,因为第一个包含 or

请帮忙。

注:defiantjs还有一个“XPath Evaluator”,您可以在其中检查查询。

最佳答案

使用 forEach 迭代数组并使用 indexOf 查找该键中是否存在所需的值

var m = {
  "Books": [{
      "title": "Book 1",
      "binding": "paperback",
      "category": "pop",
      "language": "english",
      "author": "male"
    },
    {
      "title": "Book 2",
      "binding": "hardcover",
      "category": "pop rock,electro pop",
      "language": "french",
      "author": "female"
    },
    {
      "title": "Book 3",
      "binding": "audiobook",
      "category": "soft rock",
      "language": "german",
      "author": "male,female"
    },
    {
      "title": "Book 4",
      "binding": "boxed set",
      "category": "rock,classic rock",
      "language": "english",
      "author": "female,male"
    },
    {
      "title": "Book 5",
      "binding": "paperback",
      "category": "electro pop,rock,classic rock",
      "language": "french",
      "author": "male/female"
    },
    {
      "title": "Book 6",
      "binding": "paperback",
      "category": "rock",
      "language": "french",
      "author": "male"
    }
  ]
}




// a function which accepts key which is one of binding,category,language,author.
// the array will be filtered on this key
function getFilteredElement(key, value) {
    var bookFilter = [];
    m.Books.forEach(function(item){
       var getFilterField = item[key];
       // since the value is a string, so splitting it and creating an array
       var keyArray = item[key].split(',');
       // now checking if the passed value has a presence in the  above array
       if (keyArray.indexOf(value) !== -1) {
           // if present pushed the book name
           bookFilter.push(item.title);
       }
   });
    // returning the array of books
    return bookFilter;
}

console.log(getFilteredElement('category', 'rock'))

关于javascript - 使用 Javascript 搜索具有精确标签的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47766348/

相关文章:

javascript - 无法在 extJS 窗口上设置高度

JavaScriptCore:尝试将 JS 函数作为 block 传递给 Objective-C,出现 'TypeError' 异常

javascript - 按钮的文本垂直和水平对齐问题

javascript - 简单的 jQuery Accordion - 在可见的地方隐藏按钮

c# - 检查响应字符串是 JSON 对象还是 XML?

javascript - 检查 store vuex 中的 json 数组是否为空

javascript - 在 JSON.stringify 中使用变量

javascript - 使用 jest-image-snapshot 比较图像时如何忽略 body 标签中的区域或元素?

javascript - 无限的 Google Places 实例

javascript - 使用 jQuery 构建 XML 请求的最快方法