System.Xml.Linq.XContainer.Element(...) returned null

98 views Asked by At

I have postXmlData method to post request and get response in Xml. After receiveng responce I am trying to show attributes name startswith ("f"), but getting error System.Xml.Linq.XContainer.Element(...) returned null. What am I doing wrong?

postXmlData

public static XmlDocument postXMLData(string xml)
        {
            var request = (HttpWebRequest)WebRequest.Create(Requests.url);
            byte[] bytes;
            bytes = System.Text.Encoding.ASCII.GetBytes(xml);
            request.ContentType = "text/xml; encoding='utf-8'";
            request.ContentLength = bytes.Length;
            request.Method = "POST";
            Stream requestStream = request.GetRequestStream();
            requestStream.Write(bytes, 0, bytes.Length);
            requestStream.Close();
            HttpWebResponse response;
            response = (HttpWebResponse)request.GetResponse();

            if (response.StatusCode == HttpStatusCode.OK)
            {
                using (var streamReader = new StreamReader(response.GetResponseStream()))
                {
                    var responseText = streamReader.ReadToEnd();
                    var result = new XmlDocument();
                    result.LoadXml(responseText);
                    return result;
                }
            }

            throw new Exception();
        }

Response from Request:

<response result="0">
    <prov>
        <getStatus result="0">
            <pay date="2023-02-08T19:44:33+03:00" fatal="false" id="8022140013003" result="0" status="2" uid="26775263057008" value-date="2023-02-08T19:44:40+03:00">
            </pay>
        </getStatus>
    </prov>
</response>

To show attributes I am using XElement:

XmlDocument doc = postXMLData(Requests.getStatus("08022140013003"));
            XElement e = XElement.Load(new XmlNodeReader(doc));
            Console.WriteLine(e); //here ok
           
            IEnumerable<XAttribute> attrs1 = e.Element("response").Element("prov").Element("getStatus").Element("pay")?.Attributes().Where(a => a.Name.LocalName.StartsWith("f"));
            Console.WriteLine(attrs1);
            Console.ReadKey();
2

There are 2 answers

0
Martin Honnen On BEST ANSWER

Given that you do e.g.

        XElement e = XElement.Load(new XmlNodeReader(doc));

the selection should be relative to the response element i.e. instead of

        IEnumerable<XAttribute> attrs1 = e.Element("response").Element("prov").Element("getStatus").Element("pay")?.Attributes().Where(a => a.Name.LocalName.StartsWith("f"));

you need

        IEnumerable<XAttribute> attrs1 = e.Element("prov").Element("getStatus").Element("pay")?.Attributes().Where(a => a.Name.LocalName.StartsWith("f"));
7
Jazz. On

Try with:

var attrs1 = e.Element("prov").Element("getStatus").Element("pay").Attributes().Where(a => a.Name.LocalName.StartsWith("f"));

You can validate this by doing:

var elements = e.Elements()

There is only 1 element and it is not response but prov.

Edit:

XmlDocument doc = postXMLData(Requests.getStatus("08022140013003"));
XElement e = XElement.Load(new XmlNodeReader(doc));
//This line:
var elementsArray = e.Elements().ToArray();
Console.WriteLine(e); //here ok
           
IEnumerable<XAttribute> attrs1 = e.Element("response").Element("prov").Element("getStatus").Element("pay")?.Attributes().Where(a => a.Name.LocalName.StartsWith("f"));
Console.WriteLine(attrs1);
Console.ReadKey();