-1

I am trying to read XML using LINQ. Previously I use XMLDocument to read but it gives an error and someone on StackOverflow encourage me to use LINQ.

Below is the code i previously used for the XMLDocument

            string soapmessage = @"<?xml version=""1.0"" encoding=""UTF - 8""?>" + "\n" + response.Content;

            XmlDocument xml = new XmlDocument();
            xml.LoadXml(soapmessage);  //loading soap message as string 

            XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);

            manager.AddNamespace("d", "http://tempuri.org/");
            manager.AddNamespace("bhr", "http://52.187.127.196:5000/api/gsowebservice.asmx");

            XmlNodeList xnList = xml.SelectNodes("//bhr:FourMonthsAhead1Response", manager);
            int nodes = xnList.Count;
            string Status = xnList[0]["FourMonthsAhead1Result"]["PlantForecastIntervals"]["PlantForecastIntervalNode"]["IntervalStartTime"].InnerText;
            Console.WriteLine(Status);
            Console.ReadLine();

I am trying to get the <IntervalStartTime> from the first <PlantForecastIntervalNode> into a datetime variable;

Below attaced the XML im trying read:

enter image description here

Below is some of the XML code. I can't paste it here because the code is 2322 lines long so I shortened the code to this.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <s:Body>
        <FourMonthsAhead1Response xmlns="http://tempuri.org/">
            <FourMonthsAhead1Result xmlns="LSS.solar.webservice">
                <PlantDescription xmlns="http://base.datacontract">*PlantName*</PlantDescription>
                <PlantForecastIntervalsCount xmlns="http://base.datacontract">2976</PlantForecastIntervalsCount>
                <ForecastStartDate xmlns="http://base.datacontract">2021-10-08T13:35:55.912612</ForecastStartDate>
                <ForecastEndDate xmlns="http://base.datacontract">2021-10-08T13:35:55.9126123</ForecastEndDate>
                <PlantForecastIntervals xmlns="http://base.datacontract">
                    <PlantForecastIntervalNode>
                        <IntervalStartTime>2021-10-01T00:00:00</IntervalStartTime>
                        <IntervalEndTime>2021-10-01T00:15:00</IntervalEndTime>
                        <IntervalLength>15</IntervalLength>
                        <ForecastResultParameter>FourMonthsAhead1</ForecastResultParameter>
                        <ForecastValue>0</ForecastValue>
                        <ValueUnit>MW</ValueUnit>
                    </PlantForecastIntervalNode>
                    <PlantForecastIntervalNode>
                        <IntervalStartTime>2021-10-01T00:15:00</IntervalStartTime>
                        <IntervalEndTime>2021-10-01T00:30:00</IntervalEndTime>
                        <IntervalLength>15</IntervalLength>
                        <ForecastResultParameter>FourMonthsAhead1</ForecastResultParameter>
                        <ForecastValue>0</ForecastValue>
                        <ValueUnit>MW</ValueUnit>
                    </PlantForecastIntervalNode>
                </PlantForecastIntervals>
            </FourMonthsAhead1Result>
        </FourMonthsAhead1Response>
    </s:Body>
</s:Envelope>

Update

After exploring other threads on StackOverflow I come up with this line below but receive another error of System.UriFormatException: 'Invalid URI: The Uri string is too long.':

XDocument xdoc = XDocument.Load(soapmessage);

            var ids = xdoc.Element("FourMonthsAhead1Result")
                 .Elements("PlantForecastIntervals")
                 .Elements("<PlantForecastIntervalNode>")
                 .Select(item => item.Element("IntervalStartTime").Value);
            Console.WriteLine(ids);
Daniel
  • 109
  • 1
  • 13
  • 3
    What line causes the error and what is the error? Please provide your XML as text in case a respondent wants to copy-and-paste and test it for themselves. – Lance U. Matthews Oct 08 '21 at 06:01
  • 2
    Might you please [edit] your question to include your XML as **text** rather than as a screenshot? It's requested here not to to use images for textual data, see [*Discourage screenshots of code and/or errors*](https://meta.stackoverflow.com/a/307500) and [*Why not upload images of code on SO when asking a question*](https://meta.stackoverflow.com/a/285557) for why. A [mcve] with code and XML that does not work would increase your chances of getting an answer, for why see [ask]. – dbc Oct 08 '21 at 06:02
  • "Do you have a C# problem? Use LINQ!" - in all seriousness, if you had some "looping over an xml document" problem before, LInQ is unlikely to be the solution – Caius Jard Oct 08 '21 at 06:03
  • I've edited and inserted the XML code above as text. I am sorry for the inconvinience. – Daniel Oct 08 '21 at 06:15
  • You should migrate to `System.Xml.Linq` world. [Here](https://learn.microsoft.com/en-us/dotnet/standard/linq/linq-xml-overview) in the official docs can be a good start. – momvart Oct 08 '21 at 06:36
  • Ive tried with LINQ but now im getting a new error of ```System.UriFormatException: 'Invalid URI: The Uri string is too long.'``` – Daniel Oct 08 '21 at 07:16

2 Answers2

0

Try this using LINQ

var response = File.ReadAllText("XMLFile1.xml");
var xe = XElement.Parse(response);
XNamespace ns = "http://base.datacontract";
var obj = xe.Descendants(ns + "PlantForecastIntervals")
            .Descendants(ns + "PlantForecastIntervalNode")
            .Select(x => x.Element(ns + "IntervalStartTime").Value);
Console.WriteLine(obj);
Krishna Varma
  • 4,238
  • 2
  • 10
  • 25
-1

Look at below solution,

 var xmlRead = File.ReadAllText(@"XMLFile1.xml"); /// Add your xml file path
        var xElement = XElement.Parse(xmlRead);
        XNamespace xNamespace = "http://base.datacontract";
        var obj = xElement.Descendants(xNamespace + "PlantForecastIntervals")
                    .Descendants(xNamespace + "PlantForecastIntervalNode")
                    .Select(x => x.Element(xNamespace + "IntervalStartTime").Value);

        string[] dateTime = obj.ToArray();
    
        foreach (string x in dateTime)
        {
            Console.WriteLine(x.ToString()); /// it will print time from all IntervalStartTime tags
        }
Nilesh
  • 1
  • 3
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 13 '21 at 12:49
  • The core of this answer — the LINQ code that actually retrieves the `` values — is nearly identical to [Krishna Muppalla's answer](https://stackoverflow.com/a/69493199/150605); only some variable names are different. Also, `obj` is an `IEnumerable`, so you can enumerate it directly without creating a `string[]` from it. – Lance U. Matthews Oct 14 '21 at 08:19