Как вычислить позицию XPath элемента с использованием Javascript?

Допустим, у меня есть большой HTML-файл с различными видами тегов, похожий на StackOverflow, который вы ' Посмотрим прямо сейчас.

Теперь давайте предположим, что вы щелкаете элемент на странице, как будет выглядеть функция Javascript, которая вычисляет самый простой XPath, который ссылается на этот конкретный элемент?

Я знаю, что существует бесконечное множество способов. ссылки на этот элемент в XPath, но я ищу что-то, что просто смотрит на дерево DOM, без учета идентификаторов, классов и т. д.

Пример:


Fruit

  1. Bananas
  2. Apples
  3. Strawberries

Допустим, вы нажимаете Яблоки . Функция Javascript будет возвращать следующее:

/html/body/ol/li[2]

Она будет в основном просто проходить вверх по дереву DOM вплоть до HTML-элемента.

Просто для пояснения, обработчик события «при нажатии» не является проблема. Я могу сделать эту работу. Я просто не уверен, как рассчитать положение элемента в дереве DOM и представить его как XPath.

PS

Теперь давайте предположим, что вы щелкаете по элементу на странице, как будет выглядеть функция Javascript, которая вычисляет самый базовый XPath, который ссылается на этот конкретный элемент?

Я знаю, что существуют бесконечные способы ссылки на этот элемент в XPath, но я ищу что-то, что просто смотрит на дерево DOM, без учета идентификаторов, классов и т. Д.

Пример:


Fruit

  1. Bananas
  2. Apples
  3. Strawberries

Допустим, вы нажимаете Apples . Функция Javascript будет возвращать следующее:

/html/body/ol/li[2]

Она будет в основном просто проходить вверх по дереву DOM вплоть до HTML-элемента.

Просто для пояснения, обработчик события «при нажатии» не является проблема. Я могу сделать эту работу. Я просто не уверен, как рассчитать положение элемента в дереве DOM и представить его как XPath.

PS

Теперь давайте предположим, что вы щелкаете по элементу на странице, как будет выглядеть функция Javascript, которая вычисляет самый базовый XPath, который ссылается на этот конкретный элемент?

Я знаю, что существуют бесконечные способы ссылки на этот элемент в XPath, но я ищу что-то, что просто смотрит на дерево DOM, без учета идентификаторов, классов и т. Д.

Пример:


Fruit

  1. Bananas
  2. Apples
  3. Strawberries

Допустим, вы нажимаете Apples . Функция Javascript будет возвращать следующее:

/html/body/ol/li[2]

Она будет в основном просто проходить вверх по дереву DOM вплоть до HTML-элемента.

Просто для пояснения, обработчик события «при нажатии» не является проблема. Я могу сделать эту работу. Я просто не уверен, как рассчитать положение элемента в дереве DOM и представить его как XPath.

PS как бы выглядела функция Javascript, которая вычисляет самый простой XPath, который ссылается на этот конкретный элемент?

Я знаю, что в XPath есть бесконечные способы ссылки на этот элемент, но я ищу что-то, что просто смотрит на Дерево DOM, без учета идентификаторов, классов и т. Д.

Пример:


Fruit

  1. Bananas
  2. Apples
  3. Strawberries

Допустим, вы нажимаете Яблоки . Функция Javascript будет возвращать следующее:

/html/body/ol/li[2]

Она будет в основном просто проходить вверх по дереву DOM вплоть до HTML-элемента.

Просто для пояснения, обработчик события «при нажатии» не является проблема. Я могу сделать эту работу. Я просто не уверен, как рассчитать положение элемента в дереве DOM и представить его как XPath.

PS как бы выглядела функция Javascript, которая вычисляет самый простой XPath, который ссылается на этот конкретный элемент?

Я знаю, что в XPath есть бесконечные способы ссылки на этот элемент, но я ищу что-то, что просто смотрит на Дерево DOM, без учета идентификаторов, классов и т. Д.

Пример:


Fruit

  1. Bananas
  2. Apples
  3. Strawberries

Допустим, вы нажимаете Яблоки . Функция Javascript будет возвращать следующее:

/html/body/ol/li[2]

Она будет в основном просто проходить вверх по дереву DOM вплоть до HTML-элемента.

Просто для пояснения, обработчик события «при нажатии» не является проблема. Я могу сделать эту работу. Я просто не уверен, как рассчитать положение элемента в дереве DOM и представить его как XPath.

PS я ищу что-то, что просто смотрит на дерево DOM, без учета идентификаторов, классов и т. д.

Пример:


Fruit

  1. Bananas
  2. Apples
  3. Strawberries

Допустим, вы нажимаете Яблоки . Функция Javascript будет возвращать следующее:

/html/body/ol/li[2]

Она будет в основном просто проходить вверх по дереву DOM вплоть до HTML-элемента.

Просто для пояснения, обработчик события «при нажатии» не является проблема. Я могу сделать эту работу. Я просто не уверен, как рассчитать положение элемента в дереве DOM и представить его как XPath.

PS я ищу что-то, что просто смотрит на дерево DOM, без учета идентификаторов, классов и т. д.

Пример:


Fruit

  1. Bananas
  2. Apples
  3. Strawberries

Допустим, вы нажимаете Яблоки . Функция Javascript будет возвращать следующее:

/html/body/ol/li[2]

Она будет в основном просто проходить вверх по дереву DOM вплоть до HTML-элемента.

Просто для пояснения, обработчик события «при нажатии» не является проблема. Я могу сделать эту работу. Я просто не уверен, как рассчитать положение элемента в дереве DOM и представить его как XPath.

PS on-click 'обработчик событий не проблема. Я могу сделать эту работу. Я просто не уверен, как рассчитать положение элемента в дереве DOM и представить его как XPath.

PS on-click 'обработчик событий не проблема. Я могу сделать эту работу. Я просто не уверен, как рассчитать положение элемента в дереве DOM и представить его как XPath.

PS Любой ответ с использованием или без использования библиотеки JQuery приветствуется.

PPS Я полностью новичок в XPath, поэтому я мог даже ошибиться в приведенном выше примере, но вы поймете эту идею.

Правка от 11 августа 2010 г .: Похоже, кто-то еще задал похожий вопрос: generate / получить Xpath для выбранного текстового узла

40
задан Community 23 May 2017 в 12:26
поделиться

5 ответов

Firebug может это сделать, и это открытый исходный код ( BSD ), поэтому вы можете повторно использовать их реализацию , которая не требует каких-либо библиотек.

Стороннее редактирование

Это отрывок из связанного источника выше. На всякий случай, если ссылка выше изменится. Пожалуйста, проверьте источник, чтобы воспользоваться изменениями и обновлениями или полным набором функций.

Xpath.getElementXPath = function(element)
{
    if (element && element.id)
        return '//*[@id="' + element.id + '"]';
    else
        return Xpath.getElementTreeXPath(element);
};

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

Xpath.getElementTreeXPath = function(element)
{
    var paths = [];  // Use nodeName (instead of localName) 
    // so namespace prefix is included (if any).
    for (; element && element.nodeType == Node.ELEMENT_NODE; 
           element = element.parentNode)
    {
        var index = 0;
        var hasFollowingSiblings = false;
        for (var sibling = element.previousSibling; sibling; 
              sibling = sibling.previousSibling)
        {
            // Ignore document type declaration.
            if (sibling.nodeType == Node.DOCUMENT_TYPE_NODE)
                continue;

            if (sibling.nodeName == element.nodeName)
                ++index;
        }

        for (var sibling = element.nextSibling; 
            sibling && !hasFollowingSiblings;
            sibling = sibling.nextSibling)
        {
            if (sibling.nodeName == element.nodeName)
                hasFollowingSiblings = true;
        }

        var tagName = (element.prefix ? element.prefix + ":" : "") 
                          + element.localName;
        var pathIndex = (index || hasFollowingSiblings ? "[" 
                   + (index + 1) + "]" : "");
        paths.splice(0, 0, tagName + pathIndex);
    }

    return paths.length ? "/" + paths.join("/") : null;
};
31
ответ дан 27 November 2019 в 01:27
поделиться

Функция, которую я использую для получения XPath, похожего на вашу ситуацию, использует jQuery:

function getXPath( element )
{
    var xpath = '';
    for ( ; element && element.nodeType == 1; element = element.parentNode )
    {
        var id = $(element.parentNode).children(element.tagName).index(element) + 1;
        id > 1 ? (id = '[' + id + ']') : (id = '');
        xpath = '/' + element.tagName.toLowerCase() + id + xpath;
    }
    return xpath;
}
18
ответ дан 27 November 2019 в 01:27
поделиться
function getPath(event) {
  event = event || window.event;

  var pathElements = [];
  var elem = event.currentTarget;
  var index = 0;
  var siblings = event.currentTarget.parentNode.getElementsByTagName(event.currentTarget.tagName);
  for (var i=0, imax=siblings.length; i<imax; i++) {
      if (event.currentTarget === siblings[i] {
        index = i+1; // add 1 for xpath 1-based
      }
  }


  while (elem.tagName.toLowerCase() != "html") {
    pathElements.unshift(elem.tagName);
    elem = elem.parentNode;
  }
  return pathElements.join("/") + "[" + index + "]";
}

ИЗМЕНЕНО, ЧТОБЫ ДОБАВИТЬ ИНФОРМАЦИОННЫЙ ИНДЕКС БРАКОВ

1
ответ дан 27 November 2019 в 01:27
поделиться

Нет ничего встроенного для получения xpath элемента HTML, но обратное часто встречается, например, при использовании селектора xpath jQuery .

Если вам нужно определить xpath элемента HTML, вам нужно будет предоставить для этого специальную функцию. Вот пара примеров javascript / jQuery impls для вычисления xpath.

4
ответ дан 27 November 2019 в 01:27
поделиться

Просто для удовольствия, однострочная реализация XPath 2.0 :

string-join(ancestor-or-self::*/concat(name(),
                                       '[',
                                       for $x in name() 
                                          return count(preceding-sibling::*
                                                          [name() = $x]) 
                                                 + 1,
                                       ']'),
            '/')
3
ответ дан 27 November 2019 в 01:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: