document.evaluate не возвращает правильные TextNodes XPath

Я создаю "Highlighter" для Android в WebView. Я получаю выражение XPath для выбранного диапазона в HTML с помощью функции следующим образом

/Html [1]/ ТЕЛА [1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/ текст ()[5]

Теперь я оцениваю вышеупомянутое выражение XPath через эту функцию в JavaScript

var resNode = document.evaluate('/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[5]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE ,null);
var startNode = resNode.singleNodeValue;

но я получаю startNode "ноль".

Но вот интересный момент:

если я вычислю это выражение XPath '/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]' с использованием той же функции, оно даст соответствующий узел, т.е. 'DIV'.

Разница между двумя XPath заключается в том, что предыдущие содержат текстовый узел, а позже - только div.

Но то же самое работает нормально в настольных браузерах.

Отредактированный образец HTML

<html>
<head>
<script></script>
</head>
<body>
<div id="mainpage" class="highlighter-context">
<div>       Some text here also....... </div>
<div>      Some text here also.........</div>
<div>
  <h1 class="heading"></h1>
  <div class="left_side">
    <ol></ol>
    <h1></h1>
    <div class="text_bio">
    In human beings, height, colour of eyes, complexion, chin, etc. are 
    some recognisable features. A feature that can be recognised is known as 
    character or trait. Human beings reproduce through sexual reproduction. In this                
    process, two individuals one male and another female are involved. Male produces   
    male gamete or sperm and female produces female gamete or ovum. These gametes fuse 
    to form zygote which develops into a new young one which resembles to their parent. 
     During the process of sexual reproduction 
    </div>
  </div>
  <div class="righ_side">
  Some text here also.........
  </div>
  <div class="clr">
         Some text here also.......
  </div>
</div>
</div>
</body>
</html>

получение XPath:

var selection = window.getSelection(); 
var range = selection.getRangeAt(0); 
var xpJson = '{startXPath :"'+makeXPath(range.startContainer)+      
             '",startOffset:"'+range.startOffset+
             '",endXPath:"'+makeXPath(range.endContainer)+ 
             '",endOffset:"'+range.endOffset+'"}';

функция для создания XPath:

function makeXPath(node, currentPath) {
          currentPath = currentPath || ''; 
          switch (node.nodeType) { 
          case 3:
          case 4:return makeXPath(node.parentNode, 'text()[' + (document.evaluate('preceding-sibling::text()', node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength + 1) + ']');
          case 1:return makeXPath(node.parentNode, node.nodeName + '[' + (document.evaluate('preceding-sibling::' + node.nodeName, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength + 1) + ']' + (currentPath ? '/' + currentPath : ''));
          case 9:return '/' + currentPath;default:return '';
    }
}

Я не работаю с XML, но с HTML в веб-представлении.

Я пытался использовать Rangy для сериализации и десериализации, но Rangy "Serialize" работает правильно, но не для "десериализации".

Есть идеи, ребята, что не так?

ОБНОВИТЬ

Наконец-то получили основную причину проблемы (пока нет решения:()

` что именно происходит в Android WebView. ->> Каким-то образом веб-представление Android меняет структуру DOM загруженной HTML-страницы. Несмотря на то, что DIV не содержит текстовых узлов, при выборе текста из DIV я получаю TEXTNODE для каждой отдельной строки в этом DIV. например, для одной и той же HTML-страницы в браузере Desktop и для того же выделения текста, XPath, получаемый из веб-просмотра, полностью отличается от того, который указан в Desktop Browser '


XPath from Desktop Browser:
startXPath /HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[1]
startOffset: 184 
endXPath: /HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[1]
endOffset: 342

Xpath from webview:
startXPath :/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[3]
startOffset:0 
endXPath:/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[4]
endOffset:151

1 ответ

Решение

Ну в твоем образце путь /HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[5] выбирает пятый текстовый дочерний узел div элемент

<div class="text_bio">
In human beings, height, colour of eyes, complexion, chin, etc. are 
some recognisable features. A feature that can be recognised is known as 
character or trait. Human beings reproduce through sexual reproduction. In this                
process, two individuals one male and another female are involved. Male produces   
male gamete or sperm and female produces female gamete or ovum. These gametes fuse 
to form zygote which develops into a new young one which resembles to their parent. 
 During the process of sexual reproduction 
</div>

Тот div имеет единственный текстовый дочерний узел, поэтому я не понимаю, почему text()[5] следует выбрать что-нибудь.

Другие вопросы по тегам