Нужна помощь в формировании селектора jquery с find и содержит два условия - PullRequest
1 голос
/ 03 ноября 2011

Я смотрел некоторые другие статьи здесь и в других местах, но ничего не было именно то, что я пытаюсь реализовать.

Пожалуйста, посмотрите на этот запрос xpath (используя файл mozxpath.js для клонирования функциональности IE)

var XMLObj.selectSingleNode("/Catalog/Albums/Album/Tracks/Track[../../AlbumNo='" + AlbumNo + "' and ./TrackNo = '" + TrackNo + "']");

Как я могу преобразовать это выражение в jquery?

Я попробовал следующее, чтобы начать, и он выбирает только узел AlbumNo:

$(XMLObj).find("AlbumNo:contains(" + AlbumNo + ")", "TrackNo:contains(" + TrackNo + ")");

xpathвыражение ищет узел Track, где выполняются оба условия.Как я могу переписать выражение xpath во что-нибудь дружественное к jQuery?

Спасибо.

Редактировать

Вот упрощенная версия XMLструктура:

<Catalog>
  <Albums>
    <Album>
      <AlbumNo>1</AlbumNo>
      <Tracks>
        <Track>
          <TrackNo>1</TrackNo>
        <Track>
          <TrackNo>2</TrackNo>
        <Track>
          <TrackNo>3</TrackNo>
        <Track>
          <TrackNo>4</TrackNo>
        <Track>
          <TrackNo>5</TrackNo>
        <Track>
          <TrackNo>6</TrackNo>
        <Track>
          <TrackNo>7</TrackNo>
        <Track>
          <TrackNo>8</TrackNo>
        <Track>
          <TrackNo>9</TrackNo>
        <Track>
          <TrackNo>10</TrackNo>
        <Track>
          <TrackNo>11</TrackNo>
        <Track>
          <TrackNo>12</TrackNo>
      </Tracks>
    </Album>
  </Album>
</Catalog>

Ответы [ 3 ]

1 голос
/ 03 ноября 2011

Будет полезен пример структуры XML.

Я не думаю, что вы можете достичь того же с помощью одного селектора, вам нужно использовать более сложную структуру:

$(XMLObj).find('Album').filter(function() { // filter albums by album number
    return !!$(this).find('AlbumNo').filter(function() { 
        return $(this).text() == AlbumNo;
    }).length;
}).find('Track').filter(function() { // filter tracks by track number
    return !!$(this).find('TrackNo').filter(function() { 
        return $(this).text() == TrackNo;
    }).length;
});

Было бы определенно проще, если бы числа были атрибутами элементов, а не потомками.

Причина, по которой я использую другую filter функцию вместо :contains, заключается в том, что это единственный способ поискадля точного соответствия.:contains также будет соответствовать, если текст, который вы ищете, будет только подстрокой .То есть, если вы ищете номер дорожки 1, :contains также будет соответствовать номеру дорожки 10, 11, 12 и т. Д.


Если вам нужно сделать подобноедовольно часто, может быть полезно расширить jQuery функцией, которая фильтрует элементы с определенными подэлементами с определенным содержимым.

Например:

(function($) {
    $.fn.whichContains = function(element, content) {
        return this.filter(function() {
            return !!$(this).find(element).filter(function() { 
                return $(this).text() == content;
            }).length;
        });
    };
}(jQuery));

, который можно использовать как

$(XMLObj)
  .find('Album').whichContains('AlbumNo', AlbumNo)
  .find('Track').whichContains('TrackNo', TrackNo)
1 голос
/ 03 ноября 2011

Я установил jsfiddle, который выбирает запрашиваемый элемент TrackNo в запрашиваемом элементе AlbumNo: http://jsfiddle.net/jasper/tDhLF/.

Вот селектор, который я использовал:

$(xml_string).find('AlbumNo:contains(' + AlbumNo + ')').next('tracks').find('TrackNo:contains(' + TrackNo + ')');
1 голос
/ 03 ноября 2011

разделитель запятых для включения других элементов требует, чтобы запятая была в кавычках:

$(XMLObj).find("AlbumNo:contains(" + AlbumNo + "),TrackNo:contains(" + TrackNo + ")");
...