5

我正在 WebView 中为 Android 创建“荧光笔”。我通过如下函数获取 HTML 中选定范围的 XPath 表达式

/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[5]

现在我正在通过 javascript 中的这个函数来评估上面的 XPath 表达式

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 'null'。

但是,这是有趣的一点:

如果我使用相同的函数评估这个'/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]' XPath 表达式,它会给出正确的节点,即'div'。

两个 XPath 之间的区别在于前面的 XPath 包含一个 textNode,而后面的只有 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,而是在 webview 中使用 HTML。

我尝试使用 Rangy 序列化和反序列化,但 Rangy“序列化”可以正常工作,但“反序列化”不能正常工作。

大家有什么想法,怎么回事?

更新

终于找到了问题的根本原因(还没有解决方案:()

` android webview 中到底发生了什么。-->> 不知何故,android webview 正在改变加载的 HTML 页面的 DOM 结构。即使 DIV 不包含任何 TEXTNODES,在从 DIV 中选择文本时,我也会为该 DIV 中的每一行获取 TEXTNODE。例如,对于桌面浏览器中的相同 HTML 页面和相同的文本选择,从 webview 获取的 XPath 与桌面浏览器中给出的 XPath 完全不同


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
4

1 回答 1

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]要选择任何东西。

于 2013-06-09T13:23:47.597 回答