복붙노트

[JQUERY] 어떻게 자바 스크립트를 사용하여 요소의 XPath는 위치를 계산하는?

JQUERY

어떻게 자바 스크립트를 사용하여 요소의 XPath는 위치를 계산하는?

해결법


  1. 1.방화범이 작업을 수행 할 수 있습니다, 당신은 어떤 라이브러리를 필요로하지 않는 구현을 재사용 할 수 있도록 오픈 소스 (BSD)입니다.

    방화범이 작업을 수행 할 수 있습니다, 당신은 어떤 라이브러리를 필요로하지 않는 구현을 재사용 할 수 있도록 오픈 소스 (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;
    };
    

  2. 2.나는 당신의 상황과 유사한 XPath를 얻기 위해 사용하는 함수, 그것은 jQuery를 사용합니다 :

    나는 당신의 상황과 유사한 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;
    }
    

  3. 3.그것은 요소에 대한 XPath를 반환하고 요소는 XPath에 대한 반복자.

    그것은 요소에 대한 XPath를 반환하고 요소는 XPath에 대한 반복자.

    https://gist.github.com/iimos/e9e96f036a3c174d0bf4

    function xpath(el) {
      if (typeof el == "string") return document.evaluate(el, document, null, 0, null)
      if (!el || el.nodeType != 1) return ''
      if (el.id) return "//*[@id='" + el.id + "']"
      var sames = [].filter.call(el.parentNode.children, function (x) { return x.tagName == el.tagName })
      return xpath(el.parentNode) + '/' + el.tagName.toLowerCase() + (sames.length > 1 ? '['+([].indexOf.call(sames, el)+1)+']' : '')
    }
    

    이 MDN 페이지가 같은 코드를 제공합니다 : 아마 당신은 [] .filter 메소드를 지원하지 않는 IE8에 대한 심의를 추가해야합니다.

    var xp = xpath(elementNode)
    
    var iterator = xpath("//h2")
    var el = iterator.iterateNext();
    while (el) {
      // work with element
      el = iterator.iterateNext();
    }
    

  4. 4.파이어 버그의 구현은 DOM 트리까지 element.id 더 확인하기 위해 약간 수정 될 수있다 :

    파이어 버그의 구현은 DOM 트리까지 element.id 더 확인하기 위해 약간 수정 될 수있다 :

      /**
       * Gets an XPath for an element which describes its hierarchical location.
       */
      var getElementXPath = function(element) {
          if (element && element.id)
              return '//*[@id="' + element.id + '"]';
          else
              return getElementTreeXPath(element);
      };
    
      var getElementTreeXPath = function(element) {
          var paths = [];
    
          // Use nodeName (instead of localName) so namespace prefix is included (if any).
          for (; element && element.nodeType == 1; element = element.parentNode)  {
              var index = 0;
              // EXTRA TEST FOR ELEMENT.ID
              if (element && element.id) {
                  paths.splice(0, 0, '/*[@id="' + element.id + '"]');
                  break;
              }
    
              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;
              }
    
              var tagName = element.nodeName.toLowerCase();
              var pathIndex = (index ? "[" + (index+1) + "]" : "");
              paths.splice(0, 0, tagName + pathIndex);
          }
    
          return paths.length ? "/" + paths.join("/") : null;
      };
    

  5. 5.난 그냥 textNodes와 함께 사용하기 위해 DANS '솔루션을 수정했습니다. HTML 범위 객체를 직렬화하는 매우 유용합니다.

    난 그냥 textNodes와 함께 사용하기 위해 DANS '솔루션을 수정했습니다. HTML 범위 객체를 직렬화하는 매우 유용합니다.

    /**
     * Gets an XPath for an node which describes its hierarchical location.
     */
    var getNodeXPath = function(node) {
        if (node && node.id)
            return '//*[@id="' + node.id + '"]';
        else
            return getNodeTreeXPath(node);
    };
    
    var getNodeTreeXPath = function(node) {
        var paths = [];
    
        // Use nodeName (instead of localName) so namespace prefix is included (if any).
        for (; node && (node.nodeType == 1 || node.nodeType == 3) ; node = node.parentNode)  {
            var index = 0;
            // EXTRA TEST FOR ELEMENT.ID
            if (node && node.id) {
                paths.splice(0, 0, '/*[@id="' + node.id + '"]');
                break;
            }
    
            for (var sibling = node.previousSibling; sibling; sibling = sibling.previousSibling) {
                // Ignore document type declaration.
                if (sibling.nodeType == Node.DOCUMENT_TYPE_NODE)
                    continue;
    
                if (sibling.nodeName == node.nodeName)
                    ++index;
            }
    
            var tagName = (node.nodeType == 1 ? node.nodeName.toLowerCase() : "text()");
            var pathIndex = (index ? "[" + (index+1) + "]" : "");
            paths.splice(0, 0, tagName + pathIndex);
        }
    
        return paths.length ? "/" + paths.join("/") : null;
    };
    

  6. 6.이 HTML 요소의 XPath를 얻을 내장 아무것도 없지만, 반대 JQuery와 XPath는 선택기를 사용하여 예를 들어 일반적입니다.

    이 HTML 요소의 XPath를 얻을 내장 아무것도 없지만, 반대 JQuery와 XPath는 선택기를 사용하여 예를 들어 일반적입니다.

    당신이 HTML 요소의 XPath를 결정해야하는 경우이 작업을 수행하려면 사용자 정의 기능을 제공해야합니다. 여기에 XPath를 계산하는 예를 들어, 자바 스크립트 / jQuery를의 impls 몇입니다.


  7. 7.그냥 재미,하는 XPath 2.0 하나의 라인 구현 :

    그냥 재미,하는 XPath 2.0 하나의 라인 구현 :

    string-join(ancestor-or-self::*/concat(name(),
                                           '[',
                                           for $x in name() 
                                              return count(preceding-sibling::*
                                                              [name() = $x]) 
                                                     + 1,
                                           ']'),
                '/')
    

  8. 8.만약 확실 요소 절대 XPath를 결정해야하는 경우 아래의 용액이 바람직하다.

    만약 확실 요소 절대 XPath를 결정해야하는 경우 아래의 용액이 바람직하다.

    일부 다른 답변 하나가 (잠재적으로 동일한 ID를 가진 여러 요소가 될 수 있기 때문에 신뢰성되지 않음)는 요소 ID에 부분적으로 의존하거나 실제로 (오 특정 상황에서 형제 인덱스를 생략함으로써) 주어진 것보다 더 많은 요소를 지정 XPath를 생성 .

    코드는 상기 과제를 해결하여 파이어 버그의 소스 코드에서 적응되었다.

    getXElementTreeXPath = 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;
    
            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;
                }
            }
    
            var tagName = element.nodeName.toLowerCase();
    
            // *always* include the sibling index
            var pathIndex = "[" + (index+1) + "]";
    
            paths.unshift( tagName + pathIndex );
        }
    
        return paths.length ? "/" + paths.join( "/") : null;
    };
    

  9. 9.

    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 + "]";
    }
    

    EDITED TO의 추가 형제 INDEX 정보


  10. 10.https://github.com/KajeNick/jquery-get-xpath를 사용하여

    https://github.com/KajeNick/jquery-get-xpath를 사용하여

    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="../src/jquery-get-xpath.js"></script> 
    
    <script>
        jQuery(document).ready(function ($) {
    
            $('body').on('click', 'ol li', function () {
               let xPath = $(this).jGetXpath();
    
               console.log(xPath);
            });
    
        });
    </script>
    

    콘솔이 표시됩니다 : / HTML / 바디 / OL / 리 [2]

  11. from https://stackoverflow.com/questions/3454526/how-to-calculate-the-xpath-position-of-an-element-using-javascript by cc-by-sa and MIT license