none
Read node of unusual xml - XmlDocument - Expression must evaluate to a node-set RRS feed

  • Question

  • I've read and tried many threads - this answerthis and this answer. However, they are not applicable to me as I have really not usual xml:

    var xmlString = @"<?xml version=""1.0"" encoding=""windows-1251""?>
    <GetReply>
        <InformOne>87</InformOne>
            <InfoReply>
                <![CDATA[<?xml version='1.0' encoding='UTF-8'?>
                <S:Container xmlns:S=""http://schemas.xmlsoap.org/soap/envelope/"">
                    <S:Body>
                        <ns2:getReference31IPOResponse xmlns:ns2 = ""http://service.one.com/"" >
                            <return>
                                <reference31_1IPO xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:nil=""true""/>
                                <reference31_2IPO xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:nil=""true""/>
                                <amount>0</amount>
                                <codeTypeObject>0</codeTypeObject>
                                <returnCode>4</returnCode>
                                <errorCode>0</errorCode>
                                <errorMessage>Something was wrong</errorMessage>
                                <title>Foo Data</title>
                            </return>
                        </ns2:getReference31IPOResponse>
                    </S:Body>
                </S:Container>]]>
            </InfoReply>
    </GetReply>";
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xmlString);
    
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xmlString);
    var errorMessage = xmlDoc.SelectSingleNode("/GetReply/InformOne/InfoReply/CDATA/S:Container/S:Body/ns2:getReference31IPOResponse/return/errorMessage");

    However, I see the following error:

    'Expression must evaluate to a node-set.'

    In addition, I even tried to get InfoReply, however the error is the same:

    var errorMessage = xmlDoc.SelectSingleNode("/GetReply/InformOne/InfoReply/");

    What I want is to read text in errorMessage node?

    Could you tell me please, what I am doing wrong? I need to take value by XmlDocument class. Any help would be greatly appreciated.

    Thursday, February 13, 2020 11:10 AM

All replies

  • Hi, this answer maybe is not applicable to you problem but I try to show you this tips. 

    You can create an XML class converting your XML file. You can use xmltocsharp online tool (search it on Google). So you get back an XML class and it can be used to accesso the value of your XML tags. For example, you obtain a macro class called GetReply, which contains reference to InformOne, which contains reference to InfoReply, and all the child nodes, and so on. So you can access your value in the following way:

    serializer = new XmlSerializer(typeof(GetReply));
    using (var xmlr = XmlReader.Create(path of the XML file))
    {
      reply = serializer.Deserialize(xmlr) as GetReply;
      var errorMessage = reply.InformOne.InfoReply.Container.Body.Ns2.return.ErrorMessage.Value;
    }

    Note the the names of every instance that follow the "reply" are called by the tool (so everything in "var errorMessage=" line can be called in another way).

    Hope this help

    Thursday, February 13, 2020 11:51 AM
  • CDATA is used to wrap arbitrary data so you cannot select into it as the parser doesn't understand anything. It could be just about anything including binary data. You have to extract the CDATA out of the XML and then you can treat it as XML and parse it.

    var doc = new XmlDocument();
    doc.LoadXml(xmlString);
    
    //Get the cdata
    var replyNode = doc.SelectSingleNode("/GetReply/InfoReply");            
    var cdataNode = replyNode.FirstChild as XmlCDataSection;
    if (cdataNode != null)
    {
        //Now we have the underlying XML so we can parse again
        var childDoc = new XmlDocument();
        childDoc.LoadXml(cdataNode.InnerText);
    
        //Now fetch the desired data
        var errorNode = childDoc.SelectSingleNode("//errorMessage");
        var errorMessage = errorNode?.InnerText;
    };


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, February 13, 2020 3:33 PM
    Moderator