Reputation: 470
I was creating a application that automatically inserts data into html input tags. I have xPath for specific tag like '/html/body/form/div/div[2]/div/div/input' and I managed to get HtmlNode with the help of HtmlAgilityPack
var documentAsIHtmlDocument3 = (mshtml.IHTMLDocument3)webBrowser.Document.DomDocument;
StringReader sr = new StringReader(documentAsIHtmlDocument3.documentElement.outerHTML);
htmlDocument.Load(sr);
if (htmlDocument.DocumentNode != null)
{
HtmlNode currentNode = htmlDocument.DocumentNode.SelectSingleNode(xPath);
}
Now i need to somehow select HtmlElement from Webbrowser.Document which corresponds to current HtmlNode . Can somebody help me with that?
BTW: I am not creating any spamming bot.
Hi everyone again. I found solution with recursion, lots of if statements and no htmlagilitypack, but unfortunately i can't post it right now. It seems that i don't have enough reputation.
Still, if it doesn't make too much effort, can you please tell me how to solve this problem with htmlagilitypack, because my code seems really nasty.
Upvotes: 2
Views: 6578
Reputation: 470
Thank you everyone. After thinking and programming for a almost whole day, I came to decision that i have to use native htmlElement instead of htmlagilitypack HtmlNode, because I want to input text into Htmlelement in webbrowser . so here is the code that i came up with. still i would appreciate if someone shows a solution with htmlagilitypack.
public HtmlElement selectHtmlNode(string xPath, HtmlElement htmlElement)
{
string currentNode;
int indexOfElement;
//get string representation of current Tag.
if (xPath.Substring(1,xPath.Length-2).Contains('/'))
currentNode = xPath.Substring(1, xPath.IndexOf('/', 1) - 1);
else
currentNode = xPath.Substring(1, xPath.Length-1);
//gets the depth of current xPath
int numOfOccurence = Regex.Matches(xPath, "/").Count;
//gets the children's index
int.TryParse(Regex.Match(currentNode, @"\d+").Value, out indexOfElement);
//if i have to select nth-child ex: /tr[4]
if (indexOfElement > 1)
{
currentNode = currentNode.Substring(0, xPath.IndexOf('[') - 1);
//the tag that i want to get
if (numOfOccurence == 1 || numOfOccurence == 0)
{
return htmlElement.Children[indexOfElement - 1];
}
//still has some children tags
if (numOfOccurence > 1)
{
int i = 1;
//select nth-child
foreach (HtmlElement tempElement in htmlElement.Children)
{
if (tempElement.TagName.ToLower() == currentNode && i == indexOfElement)
{
return selectHtmlNode(xPath.Substring(xPath.IndexOf('/', 1)), tempElement);
}
else if (tempElement.TagName.ToLower() == currentNode && i < indexOfElement)
{
i++;
}
}
}
}
else
{
if (numOfOccurence == 1 || numOfOccurence == 0)
{
return htmlElement.FirstChild;
}
if (numOfOccurence > 1)
{
foreach (HtmlElement tempElement in htmlElement.Children)
{
if (tempElement.TagName.ToLower() == currentNode)
{
return selectHtmlNode(xPath.Substring(xPath.IndexOf('/', 1)), tempElement);
}
}
}
}
return null;
}
function is called in this way. where htmlController is instance of some class.
HtmlElement currentElement = htmlController.selectHtmlNode("/body/form/div/div[2]/div/div/input", webBrowser.Document.GetElementsByTagName("html")[0]);
currentElement.SetAttribute("Value", "hello world");
Upvotes: 1
Reputation: 701
If you know certain position of you element you can simply get the element by
HtmlNode mynode=htmlDocument.DocumentNode.SelectSingleNode("//div[@class='fooclass']");
or you can use Select function for HtmlNodeCollection.
After getting certain node just use mynode variables Attributes,InnerHtml or InnerText properties for your needs.
for example: if your node refers an image mynode.Attributes["src"].Value will show you the image source uri.
PS: I assume htmlDocument is the class of HtmlAgilityPack.
Upvotes: 0