I have to parse html like this:
<div class="navig-nav">
<ul class="navig" id="navigmenu">
<li class="navig-expanded navig-selected">Company</li>
<li class="navig-sub"><div>Summary</div></li>
<li class="navig-sub">Some</li>
<li class="navig-sub">Interesting</li>
<li class="navig-sub">Information</li>
<li class="navig-item"><div>From</div></li>
<li class="navig-item"><div>Web</div></li>
<li class="navig-item"><div>Page</div></li>
</ul>
</div>
In this menu (as you can see) all classes has more than one child. How can I get "any_url_2" using csQuery if I have just the name "Interesting"?
What about
dom["a:contains('Interesting')"];
Well here's a more complete query:
CQ dom = "your html here";
var result = dom["a[href='any_url_2']:contains('Interesting')"];
if (result.Length == 1)
{
Console.WriteLine(result[0].Attributes["href"]);
}
Is this:
dom[".navig-sub"].Find("a:contains('Interesting')")
a good answer?
Related
I am trying to convert from html to .txt with HTML AGILITY PACK.
I would like to retain the numberings or letterings from the ordered or unordered list to keep the same rendering.
Given a HTML like :
<h1> Title </h1>
<h2> Sub Title </h2>
<ol>
<li style="list-style-type: lower-alpha;"> First element </li>
<li style="list-style-type: lower-alpha;"> Second element </li>
<li style="list-style-type: lower-alpha;"> Third element </li>
</ol>
<h3> Diferent title</h3>
<ol>
<li style="list-style-type: lower-roman;"> First element </li>
<li style="list-style-type: lower-roman;"> Second element </li>
</ol>
<h3> Diferent title</h3>
<p> Some text </p>
<ol>
<li> First element </li>
<li> Second element </li>
</ol>
<h3> Unordered list title</h3>
<ul>
<li> First element </li>
<li> Second element </li>
</ul>
I cannot find the way. I tried with this:
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
var htmlBody = htmlDoc.DocumentNode.SelectSingleNode("//body");
var lists = htmlDoc.DocumentNode.SelectNodes("//ol"); //todas las <ol>
foreach (HtmlNode node in lists)
{
var elementInList = node.SelectNodes(".//li").Count;
Console.WriteLine("elementInList "+ elementInList);
for ( int i=0; i < elementInList;i++){
Console.WriteLine( i+1 + ". "+ node.SelectNodes(".//li")[i].InnerHtml);
}
But I do want it to appear in the text like that, to substitute the < li > in order to have the position like " 1. First Element" (not in the console)
Thank you in advance
Trying to pick value in the dropdown on form.
Current HTML looks like
<div class="listing-editor__input--half d--ib va--t">
<div aria-haspopup="true" tabindex="-1" class="dropdown form__text--select d--b dropdown--expanded" aria-expanded="true">
<div class="dropdown__selector dropdown__selector--select-tag dropdown__selector--select-tag--large">
<p data-et-name="category" class="tc--lg">
Select Subcategory (optional)
</p>
</div>
<div>
<ul class="dropdown__menu">
<li class="dropdown__menu__item"><a class="dropdown__link">Belts</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Glasses</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Gloves & Mittens</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Hair Accessories</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Hats</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Hosiery & Socks</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Key & Card Holders</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Laptop Cases</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Phone Cases</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Scarves & Wraps</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Sunglasses</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Tablet Cases</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Umbrellas</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">Watches</a></li>
<li class="dropdown__menu__item"><a class="dropdown__link">None</a></li>
</ul>
</div>
</div>
<p class="form__error-message" style="display: none;">
</p>
</div>
And im trying to pick by string "Phone"
Tried with
// select the drop down list
var education = driver.FindElementByCssSelector("#content > div > div > div:nth-child(2) > section:nth-child(4) > div > div.col-x24.col-l20 > div:nth-child(1) > div > div.dropdown__selector.dropdown__selector--select-tag.dropdown__selector--select-tag--large");
//create select element object
var selectElement = new SelectElement(education);
// select by text
selectElement.SelectByText("Phone");
Output
OpenQA.Selenium.Support.UI.UnexpectedTagNameException: 'Element should have been select but was div'
Edit>
SelectElement can be used only with HTML select tag. Steps to select the dropdown in HTML you provided:
click on dropdown to expand it
find and click on "option" element.
using (IWebDriver driver = new ChromeDriver())
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
driver.Navigate().GoToUrl("https://poshmark.com/create-listing");
driver.FindElement(By.Id("login_form_username_email")).SendKeys("username");
driver.FindElement(By.Id("login_form_password")).SendKeys("password");
driver.FindElement(By.TagName("button")).Click();
wait.Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("input[data-vv-name='title']"))).SendKeys("Title controled by t3cho");
driver.FindElement(By.CssSelector("[data-vv-name='originalPrice']")).SendKeys("22");
var categoryCombobox = driver.FindElement(By.XPath("//span[#data-et-name='category']/ancestor::div[contains(#class,'isting-editor__input--half')][1]"));
js.ExecuteScript("arguments[0].scrollIntoView(false)", categoryCombobox);
categoryCombobox.Click();
var category1 = driver.FindElement(By.LinkText("Accessories"));
js.ExecuteScript("arguments[0].scrollIntoView(false)", category1);
category1.Click();
var category2 = driver.FindElement(By.LinkText("Glasses"));
js.ExecuteScript("arguments[0].scrollIntoView(false)", category2);
category2.Click();
}
Download SeleniumExtras.WaitHelpers NuGet Package for ExpectedConditions.
Try this:
new SelectElement(driver.FindElement(By.Xpath("//ul[#class='dropdown__menu']"))).SelectByText("Phone Cases");
I has a problem to creating HTML-list base on array in c#.
I tried using split.string, foreach, and etc,. but still can't figured out the logic... :(..
Anyone can help me to solve my problem ?
Here is my Array
List<string> listMenu = new List<string>();
listMenu.Add("Dashboard~View1");
listMenu.Add("Dashboard~View2");
listMenu.Add("Customer");
listMenu.Add("Part");
listMenu.Add("Part~Part1~Part11");
listMenu.Add("Part~Part1~Part12");
listMenu.Add("Part~Part2~Part21");
listMenu.Add("Part~Part2~Part22");
listMenu.Add("Part~Part3~Part31~Part311");
listMenu.Add("Part~Part3~Part31~Part312");
listMenu.Add("Branch");
And I want to create HTML list like this :
<div id=menu>
<ul>
<li>Dahboard
<ul>
<li> View1 </li>
<li> View2 </li>
</ul>
</li>
<li> Customer
</li>
<li> Part
<ul>
<li> Part1
<ul>
<li> Part11
</li>
<li> Part12
</li>
</ul>
</li>
<li> Part2
<ul>
<li> Part21
</li>
<li> Part22
</li>
</ul>
</li>
<li> Part3
<ul>
<li> Part31
<ul>
<li> Part 311
</li>
</ul>
</li>
<li> Part 312
</li>
</ul>
</li>
</ul>
</li>
<li> Branch
</li>
</ul>
</div>
There are two ways you can use to create this list dynamically:
You can use HtmlGenericControl structure as below:
HtmlGenericControl c = new HtmlGenericControl("div");
c.Attributes.Add("id", "menu");
HtmlGenericControl ul1 = new HtmlGenericControl("ul");
c.Controls.Add(ul1);
HtmlGenericControl li1 = new HtmlGenericControl("li");
li1.InnerText = "Dashboard";
ul1.Controls.Add(li1);
mainDiv.Controls.Add(c);
You can create a string with StringBuilder and assign this string as InnerHtml to your main div, as below:
StringBuilder s = new StringBuilder();
s.Append(#"<div id=menu>
<ul>
<li>Dahboard
<ul>
<li> View1 </li>
<li> View2 </li>
</ul>
</li>
</ul>
</div> "); //you can alter this string dynamically
mainDiv.InnerHtml = s.ToString();
You should add System.Web.UI.HtmlControls as using to use
HtmlControls
You should add System.Text as using in order to use StringBuilder.
Bonus: You can find from here why you should use StringBuilder
instead of adding string with '+'.
This is my HTML code. How to select first link(Main link 1, Main link 2,...) after <li id="item1"> ,<li id="item2"> and etc.
<div id="mainmenu">
<div class="wrapper">
<div class="main-menu">
<ul class="navigation">
<li class="menu-group">
<ul>
<li id="item1">
Main link 1
<div id="item1-sub">
<ul>
<li>
subLink1
</li>
<li>
subLink2
</li>
</ul>
</div>
</li>
<li id="item2">
Main link 2
<div id="item2-sub">
<ul>
<li>
subLink1
</li>
<li>
subLink2
</li>
</ul>
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
C# code:
This code has problems. I hope someone can help to solve problems.
var webGet = new HtmlWeb();
var document = webGet.Load("file.html");
var menuGroup = document.DocumentNode.SelectNodes("//div[#id='mainmenu']//div[#class='wrapper']//div[#class='main-menu']//ul[#class='navigation']//li[#class='menu-group']//ul//li");
if (menuGroup != null)
{
foreach (var Tag in menuGroup)
{
var atag = Tag.SelectSingleNode("./a");
}
}
You could do this
var html = "<html><head></head><body><div id=\"mainmenu\"><div class=\"wrapper\"><div class=\"main-menu\"><ul class=\"navigation\"><li class=\"menu-group\"><ul><li id=\"item1\">" +
"Main link 1<div id=\"item1-sub\"><ul><li>subLink1</li><li>subLink2</li></ul></div></li><li id=\"item2\">" +
"Main link 2<div id=\"item2-sub\"><ul><li>subLink1</li><li>subLink2</li></ul></div></li></ul></li></ul></div></div></div></body></html>";
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var mainLink1 = doc.DocumentNode.SelectSingleNode("//li[#id='item1']//a");
var linkUrl1 = mainLink1.Attributes["href"].Value;
var linkText1 = mainLink1.InnerText;
var mainLink2 = doc.DocumentNode.SelectSingleNode("//li[#id='item2']//a");
var linkUrl2 = mainLink2.Attributes["href"].Value;
var linkText2 = mainLink2.InnerText;
OUTPUT:
EDIT:
Use the following code to get main links with loop, This will pick only your desired links.
foreach (var div in doc.DocumentNode.SelectNodes("//li[#class='menu-group']//ul//li//div"))
{
div.InnerHtml = string.Empty;
}
foreach (var a in doc.DocumentNode.SelectNodes("//li[#class='menu-group']//ul//li//a"))
{
var linkUrl = a.Attributes["href"].Value;
var linkText = a.InnerText;
}
I have the following HTML
<div id='cssmenu'>
<ul>
<li class= 'has-sub'>
<a href=store.aspx?id=dLYTWvt8EsHOq7Ps2wJA9A%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat</span></a>
<ul>
<li class= 'has-sub'>
<a href=store.aspx?id=xEDEzZWDRkX8%2fbXoMX2pSQ%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-2</span></a>
<ul>
<li class= 'active'><a href=store.aspx?id=TxlSRrnSZ6HDgj%2b2ZSxRhg%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Dance -1</span></a></li>
<li class= 'active'><a href=store.aspx?id=Y7JxNAXSuG1T%2f0cpjQXSwA%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Dance - 2</span></a></li>
<li class= 'active'><a href=store.aspx?id=%2fcoJMcJTjWp3%2bPuimR5AhA%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-5</span></a></li>
</ul>
</li>
<li class= 'has-sub'>
<a href=store.aspx?id=KC2g4igBzXisbsbKu%2fKrzw%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-3</span></a>
<ul>
<li class= 'active'><a href=store.aspx?id=8DCHnP%2b4KQVYDTGxVt9snQ%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Death -1</span></a></li>
<li class= 'active'><a href=store.aspx?id=nGEm4rbNMQ%2bQfyO44ECmpA%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Death - 1</span></a></li>
</ul>
</li>
<li class= 'has-sub'><a href=store.aspx?id=feki%2bXDs66obnO1e2dxHWg%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-4</span></a></li>
<li class= 'has-sub'><a href=store.aspx?id=5O394Lww9oxD1vHbIY7LWw%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Armed Combat 1-6</span></a></li>
</ul>
</li>
<li class= 'active'><a href=store.aspx?id=RIe63RBggHzj76SUwDHKMg%3d%3d&digest=tNy7s/jOrynR4pvMVN6d6Q==><span>Dance</span></a></li>
</ul>
</div>
And in reqid
var reqid = "<%=Request["id"]%>";
In reqid I will get urlencoded based on menu selection
My jQuery code here
$(function () {
var str = $("#cssmenu").find('li').find('a').attr('href');
if ($(str).has(reqid)) {
var str2 = $("#cssmenu").find('li').find('a').text();
$('#selectedmenuitem').html(str2);
}
});
If the href attribute encoded url contains selected menu item encodedurl i want to get the matched url .text() to the #selectedmenuitem label id.
I checked with contains, am not getting. Please suggest me what are other possibilities for this.
use indexOf function of Javascript
http://www.w3schools.com/jsref/jsref_indexof.asp
Use following jquery code
$(function () {
var str2= $("#cssmenu").find("li").find("a[href*='" + reqid + "']").text();
$('#selectedmenuitem').html(str2);
});