Search code examples
xmllinqc#-4.0xelement

C# Linq to XML Element


Working on an issue where I can't seem to step through the elements and convert the date value as a datetime from the xml then print out all elements where the date is greater than "x" date to the console. The XML file is rather large, but here is a sample.

<DataSet>
   <diffgr:diffgram xmls="">
       <NewDataSet>
          <USER_LOGIN>
              <USER_LOGIN_ID>123</USER_LOGIN_ID>
              <DATE>2017-03-01T16:56:16.59-06:00</<DATE>
          </USER_LOGIN>
          <CONTENT>
              <CONTENT_ID>123</CONTENT_ID>
              <DATE>2017-03-01T16:56:16.59-06:00</<DATE>
          </CONTENT>
              ETC. ETC.
       <NewDataSet>
   </diffgr:diffgram> 
<DataSet>

In my code I have a list which I am wanting to read through and output all elements inside where date is greater than 'some hardcoded date'. I realize I can have a foreach loop for every element inside the descendant of but I want this to be dynamic because there are many more elements this must loop through than in my sample. Here is my current code. This fails and shows Null exception on the where clause in my code. If I remove the where clause it prints all elements in .

XDocument doc= XDocument.Load("xmlfile.xml");
DateTime testDate= new DateTime(2017, 03, 01);

IEnumerable<XElement> textSeg=
      from element in doc.Descendants("NewDataSet")
      where (DateTime)element.Element("DATE")>testDate
      select element;

      foreach (XElement element in textSeg)
         {Console.Writeline(element);}

Solution

  • You are attempting to get DATE elements from the USER_LOGIN element and CONTENT elements directly; you need to visit their child elements.

    (please excuse my use of method syntax over query syntax, this is what I prefer)

    gist here

    var dateElements = doc.Descendants("NewDataSet")
    
    // gather all the child-elements of all NewDataSet elements
    .SelectMany(dataSetEle => dataSetEle.Elements())
    
    // filter out child-elements that themselves have no applicable DATE child-elements
    .Where(childEle => childEle.Elements()
        .Any(grandChildEle =>
            grandChildEle.Name == "DATE" && (DateTime) grandChildEle > testDate)
    );