В примере приложения 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);
}
Результат выполнения этого кода выглядит следующим образом:
Теперь я хотел бы использовать ту же технику для выбора нескольких узлов <li>
под узлом <ul>
, и я пишу:
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
не является нулевой, а ее тип значения — COM Object
, но к какому более конкретному типу может быть приведено это COM Object
, мне неясно.
Есть ли способ выбрать несколько узлов с помощью используемой здесь техники?
[ОТРЕДАКТИРОВАНО]
xPath = "ul//*";
to
xPath = "//ul//*";
[Дополнение]
Я добавил две функции javaScript в свой пример 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>
Теперь, когда я запускаю следующую строку кода С# в моем методе cmd_TestClick
:
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 "
И когда я запускаю следующую строку кода C# в своем методе cmd_TestClick
:
var elements = webBrowser1.Document.InvokeScript("eval", new object[] { "GetElements('//ul')" });
Я получаю COM Object
, которое не могу преобразовать в IEnumerable<mshtml.IHtmlElement>
.
Есть ли способ обработать в коде С# коллекцию javaScript узлов HTML, возвращаемую
var elements = webBrowser1.Document.InvokeScript("eval", new object[] { "GetElements('//ul')" });
?