【发布时间】:2014-10-10 21:34:36
【问题描述】:
在 C# WinForms 示例应用程序中,我使用 WebBrowser 控件和 JavaScript-XPath 选择单个节点并通过以下代码更改该节点 .innerHtml:
private void MainForm_Load(object sender, EventArgs e)
{
webBrowser1.DocumentText = @"
<html>
<head>
<script src=""http://svn.coderepos.org/share/lang/javascript/javascript-xpath/trunk/release/javascript-xpath-latest-cmp.js""></script>
</head>
<body>
<img alt=""0764547763 Product Details""
src=""http://ecx.images-amazon.com/images/I/51AK1MRIi7L._AA160_.jpg"">
<hr/>
<h2>Product Details</h2>
<ul>
<li><b>Paperback:</b> 648 pages</li>
<li><b>Publisher:</b> Wiley; Unlimited Edition edition (October 15, 2001)</li>
<li><b>Language:</b> English</li>
<li><b>ISBN-10:</b> 0764547763</li>
</ul>
</body>
</html>
";
}
private void cmdTest_Click(object sender, EventArgs e)
{
string xPath = "//li";
string code = string.Format("document.evaluate('{0}', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;", xPath);
var li = webBrowser1.Document.InvokeScript("eval", new object[] { code }) as mshtml.IHTMLElement;
li.innerHTML = string.Format("<span style='text-transform: uppercase;font-family:verdana;color:green;'>{0}</span>", li.innerText);
}
这段代码运行结果如下:
现在我想使用相同的技术在<ul> 节点下选择多个<li>nodes,我正在写:
xPath = "//ul//*";
code = string.Format("document.evaluate('{0}', document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);", xPath);
var allLI = webBrowser1.Document.InvokeScript("eval", new object[] { code }) as mshtml.IHTMLElementCollection;
但是allLI变量的返回值是NULL。
如果我会写
xPath = "//ul//*";
code = string.Format("document.evaluate('{0}', document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);", xPath);
var allLI = webBrowser1.Document.InvokeScript("eval", new object[] { code });
那么返回的 allLI 变量不是 null 并且它的值类型是 COM Object 但是这个 COM Object 可以转换为更具体的类型我不清楚。
有没有办法通过这里使用的技术来选择多个节点?
[已编辑]
xPath = "ul//*";
到
xPath = "//ul//*";
[加法]
我在示例 HTML 中添加了两个 javaScript 函数:
<script type=""text/javascript"">
function GetElementsText (XPath) {
var xPathRes = document.evaluate ( XPath, document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var nextElement = xPathRes.iterateNext ();
var text = """";
while (nextElement) {
text += nextElement.innerText;
nextElement = xPathRes.iterateNext ();
}
return text;
};
function GetElements (XPath) {
var xPathRes = document.evaluate ( XPath, document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var nextElement = xPathRes.iterateNext ();
var elements = new Object();
var elementIndex = 1;
while (nextElement) {
elements[elementIndex++] = nextElement;
nextElement = xPathRes.iterateNext ();
}
return elements;
};
</script>
现在,当我在 cmd_TestClick 方法中运行以下 C# 代码行时:
var text = webBrowser1.Document.InvokeScript("eval", new object[] { "GetElementsText('//ul')" });
我正在获取所有 li 元素的文本:
"Paperback: 648 pages \r\nPublisher: Wiley; Unlimited Edition edition (October 15, 2001) \r\nLanguage: English \r\nISBN-10: 0764547763 "
当我在 cmd_TestClick 方法中运行以下 C# 代码行时:
var elements = webBrowser1.Document.InvokeScript("eval", new object[] { "GetElements('//ul')" });
我收到了COM Object,我无法将其转换为IEnumerable<mshtml.IHtmlElement>。
有没有办法在 C# 代码中处理由返回的 HTML 节点的 JavaScript 集合
var elements = webBrowser1.Document.InvokeScript("eval", new object[] { "GetElements('//ul')" });
?
【问题讨论】:
-
@Noseratio:我想避免使用 HTML Agility Pack - 我想通过 mshtml.IHTMLElement 和/或 mshtml.IHTMLElementCollection 通过 mshtml.IHTMLElementCollection 直接操作 WebBrowser 控件的 DOM 内容。
标签: c# javascript xpath webbrowser-control evaluate