Returning the specific string Any() is finding - c#

What i am trying to do here is search in a few .txt files for certain string that may exist in the HTML of a webpage, the code is working fine:
Code:
var b_c = File.ReadAllLines(#"LogicFiles\Blogs\blogs.txt");
var f_t = File.ReadAllLines(#"LogicFiles\Forums\forums.txt");
if (b_c.Any(html.Contains))
{
platform_type = "BLOG";
}
if (f_t.Any(html.Contains))
{
platform_type = "FORUM";
}
The code works as intended, what i'm trying to do now is return the specific string that is found, 1 text file is 20 strings long, it would be good if i could see the string that was marked as found in the HTML, i cannot think of a way to do this, ior is it even possible with the code as it is? any help would be appreciated.

How about doing
var found = b_c.FirstOrDefault(html.Contains);
if(found != null)
{
Console.WriteLine(found);
}

Why don't you try with .FirstOrDefault(a => a.Contains("your string"))?
In the example below you can do anything you like with the variables.
Also I strongly suggest you to read more about naming conventions in C#. You can check https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions for example.
var b_c = File.ReadAllLines(#"LogicFiles\Blogs\blogs.txt");
var f_t = File.ReadAllLines(#"LogicFiles\Forums\forums.txt");
var blog = b_c.FirstOrDefault(html.Contains);
if (blog != null)
{
platform_type = "BLOG";
}
var forum = f_t.FirstOrDefault(html.Contains);
if (forum != null)
{
platform_type = "FORUM";
}

Related

How to check if a string is in an array

I am trying to check whether a string is in an array and if continues even though the fileInfo.Name.Contains a string that is in files.Any:
\\FILES LIKE DATABASE.MDB IS IN C:PROJECTS\HOLON\DATABASE.MDB
**if (files.Any((fileInfo.Name.Contains)))**
\\DO SOMETHING
Console.WriteLine(
fileInfo.Name, fileInfo.Length,
If you alread have the filenames collected in an array, then you should either do it this way:
if (files.Any() && files.Contains(fileInfo.Name))
{
// Do something
}
If you just want to check if a file exists then you can use File.Exists:
if(System.IO.File.Exists(fileInfo.Name))
{
// Do Something
}
So you have a collection of full file paths? And you want to check if one or more of those list entries match with a specific file name?
Perhaps this would work for you:
string fileToSearch = "DATABASE.MDB";
bool found = files.Any(fileName => new FileInfo(fileName).Name.ToUpper() == fileToSearch.ToUpper());
Edit:
An alternative to constructing new FileInfo objects would be to use System.IO.Path:
bool found = files.Any(fileName => Path.GetFileName(fileName).ToUpper() == fileToSearch.ToUpper());
Edit 2:
On the other hand, if you want to search for a specific file name, and you want to use the result, you could do something like this:
var fileToSearch = "DATABASE.MDB";
var fileInfo =
(from f in files
let fi = new FileInfo(f)
where fi.Name.ToUpper() == fileToSearch.ToUpper()
select fi).FirstOrDefault();
if (fileInfo != null)
{
if (fileInfo.Exists)
{
Console.WriteLine($"{fileInfo.Name} ({fileInfo.Length} bytes).");
}
else
{
Console.WriteLine($"{fileInfo.Name} (does not exist).");
}
}
I used a LINQ query here for readability. You could use the extension methods (files.Select(f => new FileInfo(f)).Where(fi => fi.Name.ToUpper() == fileToSearch.ToUpper()).FirstOrDefault()) as well, but that's up to you.
if (Array.Exists(files, element => element.Contains(fileInfo.Name)))

How to quickly cut up and reassemble a C# List?

The setup:
I have a session variable that carries a list of IDs, pipe-delimited. The IDs are related to views in my site, and related to a breadcrumb builder.
Session["breadCrumb"] = "1001|1002|1003|1004";
If I'm on the view that corresponds to 1002, I'd like to cut everything AFTER that id out of the session variable.
I'd thought to use something like:
var curView = "1002";
if (Session["breadCrumb"] != null) {
var crumb = Session["breadCrumb"].ToString().Split('|').ToList();
var viewExists = crumb.Any(c => c.Value == curView);
if (viewExists) {
//remove everything after that item in the array.
}
}
But I'm wide open to methodologies.
You could use TakeWhile to get back only the items from the splitted list that precede the currentView.
var curView = "1002";
if (Session["breadCrumb"] != null)
{
var crumb = Session["breadCrumb"].ToString().Split('|').ToList();
var viewExists = crumb.TakeWhile(c => c != curView).ToList();
viewExists.Add(curView);
string result = string.Join("|",viewExists);
}
While this approach works I think that also the previous answer (now wrongly deleted from Mr. Andrew Whitaker) was correct. Using IndexOf should be faster with less splitting, looping, joining strings. I suggest Mr Whitaker to undelete its answer.
EDIT
This is from the deleted answer from Mr.Whitaker.
I will repost here because I think that its approach is simpler and should give better perfomances, so future readers could see also this option.
var crumb = Session["breadCrumb"].ToString()
int index = crumb.IndexOf(curView);
if (index >= 0)
{
Session["breadCrumb"] = crumb.Substring(0, index + curView.Length);
}
If Andrew decide to undelete its answer I will be glad to remove this part. Just let me know.
You could just store a List<string> in the Session directly. This saves you from having to split/concat the string manually. I know this does not answer the question directly, but I believe it is a superior solution to that.
var curView = "1002";
var crumb = Session["breadCrumb"] as List<string>;
if (crumb != null) {
var viewExists = crumb.Any(c => c.Value == curView);
if (viewExists) {
// remove everything after that item in the array.
}
}
I almost regret this, but frankly I'd just go for a regular expression:
var result = Regex.Replace(input, "(?<=(\\||^)" + current + ")(?=\\||$).*", "");
This does not directly tell you if the current view existed in the input, but even though this is also possible with the regex in this particular instance another, dead simple test exists:
var viewExists = result.Length != current.Length;

How to merge two NodebyID into one variable?

I am using Umbraco and I would like to add two variables together that will display articles in both children.
var nodes = Model.NodeById(1195).Children();
var nodes2 = Model.NodeById(1201).Children();
var test = Model.NodesById(nodes, nodes2);
It's not working and throwing an error. Is there another way to do this?
I found this on the forum board, but It doesn't seem to work for me.
link: http://our.umbraco.org/forum/developers/razor/47078-how-to-merger-DynamicNode?p=0#comment168589
Something like this perhaps?
DynamicNodeList nodes = Model.NodeById(1195).Children();
DynamicNodeList nodes2 = Model.NodeById(1201).Children();
var allNodes = nodes.Concat(nodes2);
A bit primitive (but without knowing more of the context) something like this should work:
string parentIds = "1195,1201";
string[] parentArray = parentIds.Split(',');
DynamicNodeList allNodes = new DynamicNodeList();
foreach (var x in parentArray);
foreach (var y in Library.NodeById(x).Children()) {
var thisNode = Library.NodeById(y);
if (thisNode.Id != 0) {
allNodes.Add(thisNode);
}
}
}

Logic to check for Null Value in Multiple Textboxes

Hi guys, probably a simple one.
Using C# .Net 4.0 and Visual Studio 2012 Ultimate.
Got the following code:
string part = "";
part = txtIOpart.Text;
txtBatchCV.Text = txtBatchIO.Text;
txtPartCV.Text = part;
txtExternalCV.Text = Sqlrunclass.SplitSpec_External(part, pg);
txtInternalCV.Text = Sqlrunclass.SplitSpec_Internal();
txtABSCV.Text = Sqlrunclass.SplitSpec_cvABS();
txtOilCV.Text = Sqlrunclass.SplitSpec_OilSeal();
txtBarCV.Text = "*" + Sqlrunclass.SplitInfo_ASno(part, pg) + "*";
txtBarNumCV.Text = txtBarCV.Text;
txtLocnCV.Text = Sqlrunclass.SplitInfo_Location();
txtFitsCV.Text = Sqlrunclass.SplitInfo_Desc();
txtHeightCV.Text = Sqlrunclass.SplitSpec_Height();
txtDiameterCV.Text = Sqlrunclass.SplitSpec_Diameter();
txtCirclitCV.Text = Sqlrunclass.SplitSpec_Circlit();
picTypeCV.Image = ftpclass.Download("CVspecType" + Sqlrunclass.SplitSpec_TypeCV() + ".jpg", "ftp.shaftec.com/Images/TypeJpg", "0095845|shafteccom0", "4ccc7365d4");
if (txtBatchCV.Text == null || txtBatchCV.Text == "")
{
txtBatchCV.Text = "ALL";
}
As you can see at the bottom I'm checking the batch, but I need to check all of the data thats being set by a bunch of methods. Each one will have a different txt output if it sees a null or blank txt. Is there anyway to shorten this code?
Try, txtBatchCV.Text For example
//Just for null
txtBatchCV.Text = (txtBatchCV.Text ?? "ALL").ToString();
//for both null and empty string
txtBatchCV.Text = string.IsNullOrEmpty(txtBatchCV.Text) ? "ALL": txtBatchCV.Text;
You could iterate through all the textboxes
foreach (var txt in form.Controls.OfType<TextBox>())
{
switch(txt.Id){
case "txtBatchCV":
// Do whatever you want for txtBatchCV e.g. check string.IsNullOrEmpy(txt.Text)
break;
}
}
I borrowed the above from here:
How do I loop through all textboxes and make them run corresponding actions from action dictionary?
In response to the comment I got from Tim, I've added a bit more code to explain what you could do. My code example was never meant to be a full solution.
TextBox.Text is never null, it will return "" then. If your methods return null you could use the null-coalescing operator:
string nullRepl = "ALL";
txtExternalCV.Text = Sqlrunclass.SplitSpec_External(part, pg) ?? nullRepl;
txtInternalCV.Text = Sqlrunclass.SplitSpec_Internal() ?? nullRepl;
txtABSCV.Text = Sqlrunclass.SplitSpec_cvABS() ?? nullRepl;
txtOilCV.Text = Sqlrunclass.SplitSpec_OilSeal() ?? nullRepl;
txtLocnCV.Text = Sqlrunclass.SplitInfo_Location() ?? nullRepl;
txtFitsCV.Text = Sqlrunclass.SplitInfo_Desc() ?? nullRepl;
txtHeightCV.Text = Sqlrunclass.SplitSpec_Height() ?? nullRepl;
txtDiameterCV.Text = Sqlrunclass.SplitSpec_Diameter() ?? nullRepl;
txtCirclitCV.Text = Sqlrunclass.SplitSpec_Circlit() ?? nullRepl;
For starters you could use string.IsNullOrEmpty(txtBatchCV.Text), it's a convevience method that basically does what you do in the if check.
You can atleast use one of these methods:
string.IsNullOrEmpty(txtBatchCV.Text)
or
string.IsNullOrWhitespace(txtBatchCV.Text)
I would try something like this:
void SetDefaultIfNull(TextBox txt, string defaultVal)
{
if (string.IsNullOrWhitespace(txt.Text))
txt.Text = defaultVal;
}
Then pass each textbox and the default to the method.

Better way to add a style attribute to Html using HtmlAgilityPack

I am using the HtmlAgilityPack. I am searching through all P tags and adding a "margin-top: 0px" to the style within the P tag.
As you can see it is kinda "brute forcing" the margin-top attribute. It seems there has to be a better way to do this using the
HtmlAgilityPack but I could not find it, and the HtmlAgilityPack documentation is non-existent.
Anybody know a better way?
HtmlNodeCollection pTagNodes = node.SelectNodes("//p[not(contains(#style,'margin-top'))]");
if (pTagNodes != null && pTagNodes.Any())
{
foreach (HtmlNode pTagNode in pTagNodes)
{
if (pTagNode.Attributes.Contains("style"))
{
string styles = pTagNode.Attributes["style"].Value;
pTagNode.SetAttributeValue("style", styles + "; margin-top: 0px");
}
else
{
pTagNode.Attributes.Add("style", "margin-top: 0px");
}
}
}
UPDATE: I have modified the code based on Alex's suggestions. Would still like to know if there is a some built-in
functionality in HtmlAgilityPack that will handle the style attributes in a more "DOM" manner.
const string margin = "; margin-top: 0px";
HtmlNodeCollection pTagNodes = node.SelectNodes("//p[not(contains(#style,'margin-top'))]");
if (pTagNodes != null && pTagNodes.Any())
{
foreach (var pTagNode in pTagNodes)
{
string styles = pTagNode.GetAttributeValue("style", "");
pTagNode.SetAttributeValue("style", styles + margin);
}
}
You could simplify your code a little bit by using HtmlNode.GetAttributeValue method, and making your "margin-top" magic string as constant:
const string margin = "margin-top: 0";
foreach (var pTagNode in pTagNodes)
{
var styles = pTagNode.GetAttributeValue("style", null);
var separator = (styles == null ? null : "; ");
pTagNode.SetAttributeValue("style", styles + separator + margin);
}
Not a very significant improvement, but this code is simpler as for me.
First of all, are you sure you need more than what you asked for? Alex solution should just work fine for your current problem, if it's always that "simple" why bother and add more complexity to it?
Anway, the AgilityPack doesn't have that kind of function, but surely the .Net Framework has. Note this is all for .Net 4, if you're using an earlier version things might be a bit different.
First of, System.Web.dll comes with the CssStyleCollection Class, this class already has everything build in that you could want for parsing inline css, there's just one catch, it's constructor is internal so the solution is a bit "hacky".
First off, for construction an instance of the class all you need is a bit of reflection, the code for that has already been done here. Just keep in mind that this works now, but could break in a future version of .Net.
All that's left is really easy
CssStyleCollection css = CssStyleTools.Create();
css.Value = "border-top:1px dotted #BBB;margin-top: 0px;font-size:12px";
Console.WriteLine(css["margin-top"]); //prints "0px"
IF you can't for some reason add a reference to System.Web (would be the case if you're using .Net 4 Client Profile) there's always the possibility to use Reflector.
Personally i'd go with Alex's solution, but it's up to you to decide. :)
Just use the following extension method of the HtmlNode:
public static void AddOrUpdateCssValue(this HtmlNode htmlNode, string cssKey, string cssValue)
{
string style = htmlNode.GetAttributeValue("style", "");
string newStyle = addOrUpdateCssStyleKeyValue(style: style, newKey: cssKey, newValue: cssValue);
htmlNode.SetAttributeValue(name: "style", value: newStyle);
}
private static string addOrUpdateCssStyleKeyValue(string style, string newKey, string newValue)
{
if (String.IsNullOrEmpty(style)) return style;
if (String.IsNullOrEmpty(newKey)) return style;
if (String.IsNullOrEmpty(newValue)) return style;
style = style.Clone() as string;
List<string> keyValue = style.Split(';').Where(x => String.IsNullOrEmpty(x) == false).Select(x => x.Trim()).ToList();
bool found = false;
List<string> updatedStyles = new List<string>();
foreach (string keyValuePair in keyValue)
{
if (String.IsNullOrEmpty(keyValuePair) == true) continue;
if (keyValuePair.Contains(':') == false) continue;
List<string> splitted = keyValuePair.Split(':').Where(x => String.IsNullOrEmpty(x) == false).Select(x => x.Trim()).ToList();
if (splitted == null) continue;
if (splitted.Count < 2) continue;
string key = splitted[0];
string value = splitted[1];
if (key == newKey)
{
value = newValue;
found = true;
}
updatedStyles.Add(String.Format("{0}: {1}", key, value));
}
if (found == false)
{
updatedStyles.Add(String.Format("{0}: {1}", newKey, newValue));
}
string result = String.Join("; ", updatedStyles);
return result;
}

Categories

Resources