使用带有精确标记的Javascript搜索JSON

时间:2017-12-12 06:12:14

标签: 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 + ']';

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

但现在的问题是,如果我想获得具有类型pop的图书然后使用查询//*[contains(category ,"rock")]我得到

  1. 第2册
  2. 第3册
  3. 第4册
  4. 第5册
  5. 第6册
  6. 但实际上只有第4册第5册第6册 Rock 类别。

    我尝试的另一个问题是:

    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,")] or category[contains(.,", rock")] or category ="rock"],它返回:

    1. 第2册
    2. 第4册
    3. 第5册
    4. 第6册
    5. 我能得到的最近的就是这里。

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

      1. 如何使用我点击的精确过滤器过滤图书。例如。如果我单击Rock,则只返回包含类别rock的Books。
      2. 如果我使用//*[category[contains(.,"rock,")] or category[contains(.,", rock")] or category ="rock"]并将其与主 thequeryString and一起加入,则它不会过滤掉正确的结果,因为第一个包含即可。
      3. 请帮忙。

        注意:defiantjs也有一个&#34; XPath评估员&#34;你可以在哪里检查查询。

1 个答案:

答案 0 :(得分:1)

使用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'))