【发布时间】:2013-06-08 13:25:50
【问题描述】:
我正在 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'。
但是,有趣的是:
如果我使用相同的功能,它给出了正确的节点,即“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
【问题讨论】:
-
考虑创建一个SSCCE,周围有很多不相关的代码。并且还包括一些示例 XML 来处理。
-
抱歉,删除了注释代码。我使用的是 HTML 而不是 XML 的代码。
-
请添加一些XML输入(或者HTML,到底无所谓);没有任何文件可以解决,就不可能重现您的问题。
-
添加了示例 HTML
标签: android xpath webview document.evaluate