Get '.name a' with html agility pack? - html-agility-pack

I am trying to get all links of a link when its parent class is name_of_box. I wrote the below but got nothing. How do i do this? With css i believe i can select it with .name_of_box a
var ls = htmldoc.DocumentNode.Elements("//div[#class='name_of_box']//a[#href]");

HtmlAgilityPack doesn't have the ability to directly query an attribute value. You have to loop over the list of anchor nodes. Here's one way:
var ls = new List<string>();
var nodes = htmldoc.DocumentNode.SelectNodes("//div[#class='name_of_box']//a");
nodes.ToList().ForEach(a => ls.Add(a.GetAttributeValue("href", "")));
But there is an experimental build you can look at, that will let you directly query an attribute.

It could be easily done with fizzler - a .NET library to select items from a node tree based on a CSS selector. The default implementation is based on HTMLAgilityPack and selects from HTML documents.
See:
var ls = htmldoc.DocumentNode.QuerySelectorAll(".name_of_box a");

Related

Laravel - how to pass parameter to action link from js

I'm trying to dynamically build an action link for adding items to a database in Laravel. The problem is that I need to pass a parameter with category_id, which I only get after selecting the category in html select element.
I thought about using the even onChange() on select element, and then building up the link in js function, and finally setting it to "a" element with the help of js selector. However this approach doesn't work.
var link = "{{ action('ItemController#create', [ 'id' =>"+selectedId.value+"]) }}";
document.getElementById("AddItemLink").href = link;
Is producing: http://localhost:8000/item/create/+selectedId.value+
What I need to get is: http://localhost:8000/item/create/8
If I do console.log(selectedId.value), the output is correct - 8.
Any ideas how to deal with this?
You can do that,
var link = "/item/create/"+ selectedId.value;
document.getElementById("AddItemLink").href = link;

How to change the Sorting order in SharePoint 2010 List view Web Part when Group by is applied?

Scenario:
I have created one custom list in my SharePoint 2010 Environment.
In this list, there is one choice column named Status and its values are New,Open and Closed.
On a page I have setup one view and applied Group By using this Status column.
Problem
View is rendering as shown in below image:
I want to change the order of this Status column and it should be rendered in this Sort Order : New, Open and Closed.
If I use Ascending Order it will be displayed as shown in above image and if I use Descending Order then it will be displayed like: Open, New & Closed.
Can any one help me how can I get the requested Sorting for this column? Is there any alternative way to meet my requirement?
Thanks in advance!
I searched on google and tried to find a solution but didn't find any proper solution. As far as I understand, OOTB it won't be possible to apply custom orders for the column which was used for grouping. You can sort them in Ascending order or Descending order only.
But any how, I found a patch and I was able to meet the requirement using JQuery. I applied below JQuery code on the Page, it was working like a charm:
JQuery Code
$("table[summary='GTSRequests']").each(function(){
var tbodyGroupCol = $(this).find("tbody[id*='GroupByCol']");
var grpNew = $(this).find("tbody[groupstring='%3B%23New%3B%23']");
var grpOpen = $(this).find("tbody[groupstring='%3B%23Open%3B%23']");
var grpClosed = $(this).find("tbody[groupstring='%3B%23Closed%3B%23']");
if(grpNew.length > 0){
var strGrpNewId = grpNew.attr("id").replace("titl", "tbod") + "_";
grpNew.insertAfter(tbodyGroupCol)
$("#" + strGrpNewId).insertAfter(grpNew);
}
if(grpOpen.length > 0){
var strGrpOpenId = grpOpen.attr("id").replace("titl", "tbod") + "_";
grpOpen.insertAfter("#" + strGrpNewId);
$("#" + strGrpOpenId).insertAfter(grpOpen);
}
if(grpClosed.length > 0){
var strGrpClosedId = grpClosed.attr("id").replace("titl", "tbod") + "_";
grpClosed.insertAfter("#" + strGrpOpenId);
$("#" + strGrpClosedId).insertAfter(grpClosed);
}
});
So basically using this Code, I am changing the location of HTML code and putting them as per my need. So that it looks like custom sorting.
Hope this code will help other users.

Getting prevalue id from umbraco dropdown list

I'm currently trying to implement AJAX results filtering on a certain page.
I created the dropdowns(on the client side), so that they have the umbraco prevalue id as their value.
I will then send this id to the server, rather than the text value. Then I loop through my content to find items with this same id.
The problem, however, is that I can't figure out how to get the value id from the property. Everything either returns the text value, or just a 0 value.
This is being performed in an ApiController.
These are all of the options I've tried:
IPublishedContent root = Umbraco.TypedContentAtRoot().First();
var downloads = root.Children.Where(q => q.Name == "Downloads").SingleOrDefault();
foreach (var item in downloads.Children)
{
var test = item.GetPropertyValue<int>("classification");
var testing = item.GetProperty("classification");
var testVal = testing.DataValue;
var testValToo = testing.GetValue<int>();
var testThree = testing.Value;
}
These are the results in order:
- 0
- IPublishedProperty
- "textValue"
- 0
- "textValue"
Is it possible to get the selected value id from a dropdownlist property? Or is string matching my only option to compare values?
EDIT:
Nevermind, found the solution. Posting the answer here, in case someone else needs it.
I was using the data type dropdownlist. I should have been using dropdownlist:publishing keys.
dropdownlist only ever returns a value. dropdownlist:publishing keys, however, returns the prevalue id, rather than the text value.
Source
Something like this perhaps.
library.GetPreValueAsString(node.GetProperty<int>("sectionType")).ToLower()

Is it possible to filter the descendant elements returned from an XPath query?

At the moment, I'm trying to scrape forms from some sites using the following query:
select * from html
where url="http://somedomain.com"
and xpath="//form[#action]"
This returns a result like so:
{
form: {
action: "/some/submit",
id: "someId",
div: {
input: [
... some input elements here
]
}
fieldset: {
div: {
input: [
... some more input elements here
]
}
}
}
}
On some sites this could go many levels deep, so I'm not sure how to begin trying to filter out the unwanted elements in the result. If I could filter them out here, then it would make my back-end code much simpler. Basically, I'd just like the form and any label, input, select (and option) and textarea descendants.
Here's an XPath query I tried, but I realised that the element hierarchy would not be maintained and this might cause a problem if there are multiple forms on the page:
//form[#action]/descendant-or-self::*[self::form or self::input or self::select or self::textarea or self::label]
However, I did notice that the elements returned by this query were no longer returned under divs and other elements beneath the form.
I don't think it will be possible in a plain query as you have tried.
However, it would not be too much work to create a new data table containing some JavaScript that does the filtering you're looking for.
Data table
A quick, little <execute> block might look something like the following.
var elements = y.query("select * from html where url=#u and xpath=#x", {u: url, x: xpath}).results.elements();
var results = <url url={url}></url>;
for each (element in elements) {
var result = element.copy();
result.setChildren("");
result.normalize();
for each (descendant in y.xpath(element, filter)) {
result.node += descendant;
}
results.node += result;
}
response.object = results;
» See the full example data table.
Example query
use "store://VNZVLxovxTLeqYRH6yQQtc" as example;
select * from example where url="http://www.yahoo.com"
» See this query in the YQL console
Example results
Hopefully the above is a step in the right direction, and doesn't look too daunting.
Links
Open Data Tables Reference
Executing JavaScript in Open Data Tables
YQL Editor
This is how I would filter specific nodes but still allow the parent tag with all attributes to show:
//form[#name]/#* | //form[#action]/descendant-or-self::node()[name()='input' or name()='select' or name()='textarea' or name()='label']
If there are multiple form tags on the page, they should be grouped off by this parent tag and not all wedged together and unidentifiable.
You could also reverse the union if it would help how you'd like the nodes to appear:
//form[#action]/descendant-or-self::node()[name()='input' or name()='select' or name()='textarea' or name()='label'] | //form[#name]/#*

LINQ to SQL many to many int ID array criteria query

Ok this should be really simple, but I am doing my head in here and have read all the articles on this and tried a variety of things, but no luck.
I have 3 tables in a classic many-to-many setup.
ITEMS
ItemID
Description
ITEMFEATURES
ItemID
FeatureID
FEATURES
FeatureID
Description
Now I have a search interface where you can select any number of Features (checkboxes).
I get them all nicely as an int[] called SearchFeatures.
I simply want to find the Items which have the Features that are contained in the SearchFeatures.
E.g. something like:
return db.Items.Where(x => SearchFeatures.Contains(x.ItemFeatures.AllFeatures().FeatureID))
Inside my Items partial class I have added a custom method Features() which simply returns all Features for that Item, but I still can't seem to integrate that in any usable way into the main LINQ query.
Grr, it's gotta be simple, such a 1 second task in SQL. Many thanks.
The following query will return the list of items based on the list of searchFeatures:
from itemFeature in db.ItemFeatures
where searchFeatures.Contains(itemFeature.FeatureID)
select itemFeature.Item;
The trick here is to start with the ItemFeatures table.
It is possible to search items that have ALL features, as you asked in the comments. The trick here is to dynamically build up the query. See here:
var itemFeatures = db.ItemFeatures;
foreach (var temp in searchFeatures)
{
// You will need this extra variable. This is C# magic ;-).
var searchFeature = temp;
// Wrap the collection with a filter
itemFeatures =
from itemFeature in itemFeatures
where itemFeature.FeatureID == searchFeature
select itemFeature;
}
var items =
from itemFeature in itemFeatures
select itemFeature.Item;

Resources