Search code examples
c#xml

Difficulty parsing XML


This c# code:

HttpClient apiP21 = new();
apiP21.DefaultRequestHeaders.Add("client_secret", "thesecret");
apiP21.DefaultRequestHeaders.Add("grant_type", "client_credentials");
apiP21.DefaultRequestHeaders.Add("username", "theuser");
var tokenRequestDataContent = new StringContent("", Encoding.UTF8, "application/xml");
var tokenResponse = apiP21.PostAsync("theendpoint", tokenRequestDataContent).Result;
if (!tokenResponse.IsSuccessStatusCode)
{
    return BadRequest("Could not get Security Token");
}
string tokenResponseRaw = tokenResponse.Content.ReadAsStringAsync().Result;

XmlDocument tokenResponseXML = new();
tokenResponseXML.LoadXml(tokenResponseRaw);
XmlNamespaceManager nsmgr = new(tokenResponseXML.NameTable);
nsmgr.AddNamespace("act", "http://distributionsuite.activant.com");
XmlNode accessTokenNode = tokenResponseXML.SelectSingleNode("//act:AccessToken", nsmgr)!;
string accessToken = accessTokenNode?.InnerText!;

For some reason, I am getting null in accessTokenNode. I don't understand why.

Here is the XML visualizer output from tokenResponseRaw (I've omitted the actual token). I just need to get at the security token. What am I doing wrong?

<?xml version="1.0"?>
<act:Token xmlns:act="http://distributionsuite.activant.com"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <AccessToken>thetoken</AccessToken>
    <TokenType>Bearer</TokenType>
    <UserName>theuser</UserName>
    <ExpiresIn>86400</ExpiresIn>
    <RefreshToken/>
    <Scope>/api;/data;/odata:inv_mast,inv_loc,users,roles,pricing_library,inv_sub,serial_number</Scope>
    <SessionId>d0232f06-69fb-499d-bf41-4d8e6ae9b6c2</SessionId>
    <ConsumerUid>7</ConsumerUid>
</act:Token>

I was expecting to get the AccessToken node, but get null...


Solution

  • As already suggested by @JonSkeet, here is LINQ to XML based solution. It is available in the .Net Framework since 2007 onwards.

    c#

    void Main()
    {
        XDocument xdoc = XDocument.Parse(@"<act:Token xmlns:act='http://distributionsuite.activant.com'
               xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
               xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
            <AccessToken>thetoken</AccessToken>
            <TokenType>Bearer</TokenType>
            <UserName>theuser</UserName>
            <ExpiresIn>86400</ExpiresIn>
            <RefreshToken/>
            <Scope>/api;/data;/odata:inv_mast,inv_loc,users,roles,pricing_library,inv_sub,serial_number</Scope>
            <SessionId>d0232f06-69fb-499d-bf41-4d8e6ae9b6c2</SessionId>
            <ConsumerUid>7</ConsumerUid>
        </act:Token>");
        
        string AccessToken = xdoc.Descendants("AccessToken").SingleOrDefault()?.Value;
        Console.WriteLine($"AccessToken: {AccessToken}");
    }
    

    Output

    AccessToken: thetoken