none
Getting an xml node that appears more than once linq c# RRS feed

  • Question

  • Hi,

    I am reading in xml data to a winform using XDocument,

    my xml looks like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE>
    <Events time="20190205T150013+0100">
       <Event update="2" date="20190205" id="105">
       <EventDetails date="20190205" id="105" participants="6" 
        time="1500+0100">
       <Weather>Rain</Weather>
       <Event status="On" id="2075" name="Davidsons">
          <Number ="1"/>
          <Weight ="9st"/>
          <Section timestamp="20190205T1450+0100">
            <Cost high="250" low="125"/>
          </Section>
           <Section timestamp="20190205T1450+0100">
            <Cost high="220" low="105"/>
          </Section>
           <Section timestamp="20190205T1450+0100">
            <Cost high="200" low="100"/>
          </Section>
       </Event>
       <Event status="On" id="2075" name="Davidsons">
          <Number ="1"/>
          <Weight ="9st"/>
          <Section timestamp="20190205T1450+0100">
            <Cost high="250" low="125"/>
          </Section>
           <Section timestamp="20190205T1450+0100">
            <Cost high="220" low="105"/>
          </Section>
           <Section timestamp="20190205T1450+0100">
            <Cost high="200" low="100"/>
          </Section>
       </Event>
       <Event status="On" id="2075" name="Davidsons">
          <Number ="1"/>
          <Weight ="9st"/>
          <Section timestamp="20190205T1450+0100">
            <Cost high="250" low="125"/>
          </Section>
           <Section timestamp="20190205T1450+0100">
            <Cost high="220" low="105"/>
          </Section>
           <Section timestamp="20190205T1450+0100">
            <Cost high="200" low="100"/>
          </Section>
       </Event>
    

    Under the <Event> node there are multiple <Section> nodes, I want to get the last one only of each Event section, how can I do this?

    I am going by what I have read in other posts in the below code, I want to get the date, id and participants of <EventDetails>

    then get the very last <Section timestamp and <Cost high="" low="" of each <Event>

    var eventElements = doc.XPathSelectElements("Events");
    var items = from e in eventElements
       select new
       {
         date = e.XPathSelectElement("Events/Event/date")?.Value,
         id   = e.XPathSelectElement("Events/Event/id")?.Value
       }

    Any help would be really appreciated.


    CuriousCoder

    Tuesday, May 14, 2019 10:43 AM

Answers

  • In order to peek last <Section> elements, try this:

     

       var last_sections = d.XPathSelectElements( "//Event/Section[position()=last()]" );

     

    For each section, you can access Parent, etc., to get more details. Show a valid XML if you need something else.

    Tuesday, May 14, 2019 11:53 AM
  • Hi CuriousCoder15,

    Thank you for posting here.

    For your question, you want get some values and an xml node from the xml.

    Your xml has some problems, so you could refer to the following modified xml code.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE Events>
    <Events time="20190205T150013+0100">
      <Event update="2" date="20190205" id="105">
        <EventDetails date="20190205" id="105" participants="6"
         time="1500+0100">
        </EventDetails>
        <Weather>Rain</Weather>
      </Event>
      <Event status="On" id="2075" name="Davidsons">
        <Number firstnum="1"/>
        <Weight secondnum="9st"/>
        <Section timestamp="20190205T1450+0100">
          <Cost high="250" low="125"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="220" low="105"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="200" low="100"/>
        </Section>
      </Event>
      <Event status="On" id="2075" name="Davidsons">
        <Number firstnum="1"/>
        <Weight secondnum="9st"/>
        <Section timestamp="20190205T1450+0100">
          <Cost high="250" low="125"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="220" low="105"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="200" low="100"/>
        </Section>
      </Event>
      <Event status="On" id="2075" name="Davidsons">
        <Number test="1"/>
        <Weight test="9st"/>
        <Section timestamp="20190205T1450+0100">
          <Cost high="250" low="125"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="220" low="105"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="200" low="100"/>
        </Section>
      </Event>
    </Events>

    >>I want to get the date, id and participants of <EventDetails>

    Code:

                var doc = XDocument.Load(@"D:\Test1\test.xml");
                var eventElements = doc.XPathSelectElements("//Event/EventDetails");
                var items = from e in eventElements
                            select new
                            {
                                date = e.Attribute("date").Value,
                                id = e.Attribute("id").Value,
                                participants= e.Attribute("participants").Value
                            };
                foreach (var item in items)
                {
                    Console.WriteLine(item.date);
                    Console.WriteLine(item.id);
                    Console.WriteLine(item.participants);
                }
    >>then get the very last <Section timestamp and <Cost high="" low="" of each <Event>

    You could refer to Viorel's answer.

    Code:

                var last_sections = doc.XPathSelectElements("//Event/Section[position()=last()]");
                foreach (XElement item in last_sections)
                {
                    Console.WriteLine(item);
                }

    Result:

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Wednesday, May 15, 2019 2:57 AM
    Moderator

All replies

  • In order to peek last <Section> elements, try this:

     

       var last_sections = d.XPathSelectElements( "//Event/Section[position()=last()]" );

     

    For each section, you can access Parent, etc., to get more details. Show a valid XML if you need something else.

    Tuesday, May 14, 2019 11:53 AM
  • Hi CuriousCoder15,

    Thank you for posting here.

    For your question, you want get some values and an xml node from the xml.

    Your xml has some problems, so you could refer to the following modified xml code.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE Events>
    <Events time="20190205T150013+0100">
      <Event update="2" date="20190205" id="105">
        <EventDetails date="20190205" id="105" participants="6"
         time="1500+0100">
        </EventDetails>
        <Weather>Rain</Weather>
      </Event>
      <Event status="On" id="2075" name="Davidsons">
        <Number firstnum="1"/>
        <Weight secondnum="9st"/>
        <Section timestamp="20190205T1450+0100">
          <Cost high="250" low="125"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="220" low="105"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="200" low="100"/>
        </Section>
      </Event>
      <Event status="On" id="2075" name="Davidsons">
        <Number firstnum="1"/>
        <Weight secondnum="9st"/>
        <Section timestamp="20190205T1450+0100">
          <Cost high="250" low="125"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="220" low="105"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="200" low="100"/>
        </Section>
      </Event>
      <Event status="On" id="2075" name="Davidsons">
        <Number test="1"/>
        <Weight test="9st"/>
        <Section timestamp="20190205T1450+0100">
          <Cost high="250" low="125"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="220" low="105"/>
        </Section>
        <Section timestamp="20190205T1450+0100">
          <Cost high="200" low="100"/>
        </Section>
      </Event>
    </Events>

    >>I want to get the date, id and participants of <EventDetails>

    Code:

                var doc = XDocument.Load(@"D:\Test1\test.xml");
                var eventElements = doc.XPathSelectElements("//Event/EventDetails");
                var items = from e in eventElements
                            select new
                            {
                                date = e.Attribute("date").Value,
                                id = e.Attribute("id").Value,
                                participants= e.Attribute("participants").Value
                            };
                foreach (var item in items)
                {
                    Console.WriteLine(item.date);
                    Console.WriteLine(item.id);
                    Console.WriteLine(item.participants);
                }
    >>then get the very last <Section timestamp and <Cost high="" low="" of each <Event>

    You could refer to Viorel's answer.

    Code:

                var last_sections = doc.XPathSelectElements("//Event/Section[position()=last()]");
                foreach (XElement item in last_sections)
                {
                    Console.WriteLine(item);
                }

    Result:

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Wednesday, May 15, 2019 2:57 AM
    Moderator