Search code examples
c#xmlxmldocument

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


I've read and tried many threads - this answer, this 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? Any help would be greatly appreciated.

It looks like <![CDATA[<?xml version='1.0' encoding='UTF-8'?> breaks reading the rest nodes.


Solution

  • 1 - You forgot the namespaces, you need to add them with XmlNamespaceManager

    2 - You need to separate also your Xml in two sub Xml, one before CDATA and other after it.

    change your code to :

    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xmlString);
    
    XmlNamespaceManager mgr = new XmlNamespaceManager(xmlDoc.NameTable);
    mgr.AddNamespace("S", "http://schemas.xmlsoap.org/soap/envelope/");
    mgr.AddNamespace("ns2", "http://service.one.com/");
    mgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    
    var infoReply = xmlDoc.SelectSingleNode("//GetReply/InfoReply", mgr);
    
    XmlDocument requestDocument = new XmlDocument();
    requestDocument.LoadXml(infoReply.InnerText);
    
    var errorMessageNode = requestDocument.SelectSingleNode("/S:Container/S:Body/ns2:getReference31IPOResponse/return/errorMessage", mgr);
    string errorMessage = errorMessageNode?.InnerText;
    
    

    i hope that will help you out.