In C# WinForms sample application I have used WebBrowser control and JavaScript-XPath to select single node and change that node .innerHtml by the following code:
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);
}
The result of running this code is as the following:
Now I'd like to use the same technique to select multiple <li>
nodes under <ul>
node and I'm writing:
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;
but the returned value of allLI
variable is NULL
.
If I'll write
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 });
then the returned allLI
variable isn't null and its value type is COM Object
but what more specific type this COM Object
can be cast to is unclear for me.
Is there a way to select multiple nodes by used here technique?
[EDITED]
xPath = "ul//*";
to
xPath = "//ul//*";
[Addition]
I have added two javaScript functions to my sample HTML:
<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>
Now when I'm runnung the following C# code line within my cmd_TestClick
method:
var text = webBrowser1.Document.InvokeScript("eval", new object[] { "GetElementsText('//ul')" });
I'm getting text of all li
elements:
"Paperback: 648 pages
Publisher: Wiley; Unlimited Edition edition (October 15, 2001)
Language: English
ISBN-10: 0764547763 "
And when I'm running the following C# code line within my cmd_TestClick
method:
var elements = webBrowser1.Document.InvokeScript("eval", new object[] { "GetElements('//ul')" });
I'm getting COM Object
, which I cannot cast to IEnumerable<mshtml.IHtmlElement>
.
Is there any way to process within C# code a javaScript collection of HTML nodes returned by
var elements = webBrowser1.Document.InvokeScript("eval", new object[] { "GetElements('//ul')" });
?
See Question&Answers more detail:
os