使用AND多个兄弟选择器的Jquery选择器

3

我正在尝试使用兄弟节点的AND运算符进行选择。我有以下XML:

<PRODUCT>
  <TYPE>CAR</TYPE>
  <PRICE>23.42</PRICE>
  <COLOR>BLUE</COLOR>
  <DOORS>5</DOORS>
  <CATEGORY>
    <ITEM>23</ITEM>
  </CATEGORY>
</PRODUCT>
<PRODUCT>
  <TYPE>VAN</TYPE>
  <PRICE>23.42</PRICE>
  <COLOR>YELLOW</COLOR>
  <DOORS>4</DOORS>
  <CATEGORY>
    <ITEM>23</ITEM>
  </CATEGORY>
</PRODUCT>
<PRODUCT>
  <TYPE>CAR</TYPE>
  <PRICE>23.42</PRICE>
  <COLOR>GREEN</COLOR>
  <DOORS>4</DOORS>
  <CATEGORY>
    <ITEM>24</ITEM>
  </CATEGORY>
</PRODUCT>
<PRODUCT>
  <TYPE>CAR</TYPE>
  <PRICE>80.00</PRICE>
  <COLOR>BLUE</COLOR>
  <DOORS>5</DOORS>
  <CATEGORY>
    <ITEM>26</ITEM>
  </CATEGORY>
</PRODUCT>

我想要选择所有Type为Car、Doors为5且Category.Item为23的产品。我希望能够不必手动运行foreach循环来完成这个操作,是否有一种可以实现这个功能的选择器?


实际上,没有选择器可以匹配元素的内部文本(:contains() 只能匹配文本的子集,可能跨越多个元素)。最好使用 filter() - Frédéric Hamidi
1个回答

1

仅使用jQuery选择器无法解决问题,主要是因为jQuery的:contains选择器也匹配子字符串。如果这对您不是问题,则可以实现您想要的效果:

var match = $(xml).has('>type:contains("CAR")')
                  .has('>doors:contains("5")')
                  .has('>category>item:contains("23")');

var xml = `<PRODUCT>
<TYPE>CAR</TYPE>
<PRICE>23.42</PRICE>
<COLOR>BLUE</COLOR>
<DOORS>5</DOORS>
<CATEGORY>
<ITEM>23</ITEM>
</CATEGORY>
</PRODUCT>
<PRODUCT>
<TYPE>VAN</TYPE>
<PRICE>23.42</PRICE>
<COLOR>YELLOW</COLOR>
<DOORS>4</DOORS>
<CATEGORY>
<ITEM>23</ITEM>
</CATEGORY>
</PRODUCT>
<PRODUCT>
<TYPE>CAR</TYPE>
<PRICE>23.42</PRICE>
<COLOR>GREEN</COLOR>
<DOORS>4</DOORS>
<CATEGORY>
<ITEM>24</ITEM>
</CATEGORY>
</PRODUCT>
<PRODUCT>
<TYPE>CAR</TYPE>
<PRICE>80.00</PRICE>
<COLOR>BLUE</COLOR>
<DOORS>5</DOORS>
<CATEGORY>
<ITEM>26</ITEM>
</CATEGORY>
</PRODUCT>`;

var match = $(xml).has('>type:contains("CAR")')
                  .has('>doors:contains("5")')
                  .has('>category>item:contains("23")');

xmlResult = $('<div>').append(match).html();
console.log(xmlResult);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

迭代的替代方案

为了应对上述解决方案的限制,并且只接受精确的文本匹配,你需要进行迭代,例如使用filter

var match = $(xml).filter(function () {
    return $(this).find('>type').text() == 'CAR' &&
           $(this).find('>doors').text() == '5' &&
           $(this).find('>category>item').filter(function () { 
               return $(this).text() == '23';
           }).length > 0;
});

var xml = `<PRODUCT>
<TYPE>CAR</TYPE>
<PRICE>23.42</PRICE>
<COLOR>BLUE</COLOR>
<DOORS>5</DOORS>
<CATEGORY>
<ITEM>23</ITEM>
</CATEGORY>
</PRODUCT>
<PRODUCT>
<TYPE>VAN</TYPE>
<PRICE>23.42</PRICE>
<COLOR>YELLOW</COLOR>
<DOORS>4</DOORS>
<CATEGORY>
<ITEM>23</ITEM>
</CATEGORY>
</PRODUCT>
<PRODUCT>
<TYPE>CAR</TYPE>
<PRICE>23.42</PRICE>
<COLOR>GREEN</COLOR>
<DOORS>4</DOORS>
<CATEGORY>
<ITEM>24</ITEM>
</CATEGORY>
</PRODUCT>
<PRODUCT>
<TYPE>CAR</TYPE>
<PRICE>80.00</PRICE>
<COLOR>BLUE</COLOR>
<DOORS>5</DOORS>
<CATEGORY>
<ITEM>26</ITEM>
</CATEGORY>
</PRODUCT>`;

var match = $(xml).filter(function () {
    return $(this).find('>type').text() == 'CAR' &&
           $(this).find('>doors').text() == '5' &&
           $(this).find('>category>item').filter(function () { 
               return $(this).text() == '23';
           }).length > 0;
});

xmlResult = $('<div>').append(match).html();
console.log(xmlResult);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

注意内部的filter:需要检查所有类别项目,而不仅仅是第一个。
备注:示例XML并不是真正的有效XML,因为它没有单个根节点。最好将其称为XML片段。要有效,您需要将其包装在标记中,例如<PRODUCTS>...</PRODUCTS>。当然,上述解决方案看起来会略有不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接