Home > OS >  Using LINQ to select unknown values from files
Using LINQ to select unknown values from files

Time:06-09

I have several text files that have information within that relates to machine code. Below is a snippet of what is inside one of the files.

 <Parameter Name="Thickness" Idx="0" Val="0.8" Default="0.8" Min="0" Max="200" Show="True" Inherit="False" />

I am trying to use LINQ in order to extract information from this specific line of text. Here is what I have so far.

 var thickness = from t in text
                 where t.Contains("Thickness") && t.Contains("Idx=0") && t.Contains("Val")
                 select t;

I need to grab the 'Val' from this line of text, which should be 0.8 in this case. Please could someone enlighten me into how I can do this? I've done some research but I can't find a definitive answer.

Thank you.

CodePudding user response:

this is an example as I understood, as you try to use linq instead of multiple EZ approaches so now you can add any where condition and adjust select

void Main()
{
    string s= "<Parameter Name=\"Thickness\" Idx=\"0\" Val=\"0.8\" Default=\"0.8\" Min=\"0\" Max=\"200\" Show=\"True\" Inherit=\"False\" />";
    var doc = new XmlDocument();
    doc.LoadXml(s);
    
    var attr = doc.FirstChild
                    .Attributes
                    .Cast<XmlAttribute>()
                    .ToList()
                    .Select(s=> $"{s.Name} == {s.Value}");
    Console.Write(attr);

}

enter image description here

CodePudding user response:

Using XDocument you can convert the file to have a single root and then query with LINQ to XML.

First, convert the file to an XDocument. Note: If your file is very large or you don't want to read all the lines into memory and then create a single, very large string, you could use an IEnumerable<string> to Stream converter and File.ReadLines() to reduce the overhead.

If srcFile1 contains the lines from your file, then create the XElement collection of the lines with:

var data1 = XDocument.Parse("<data>"   srcFile1.Join('\n')   "</data>").Root.Elements();

Note: Join is the obvious extension method.

Now you can query the lines and pull out the Val attribute value:

var ans = data1.Where(d => d.AttrVal("Name") == "Thickness" && d.AttrVal("Idx") == "0" && d.HasAttr("Val"))
               .Select(d => d.AttrVal("Val"))
               .ToList();

I used some simple extension methods to make it a bit shorter:

public static class XMLExt {
    public static string AttrVal(this XElement x, string name) => x.Attribute(name)?.Value;
    public static bool HasAttr(this XElement x, string name) => x.Attribute(name) != null;
}
  • Related