Search code examples
c#xmlxpathxml-parsingzimbra

XML Parsing using XmlNode


In My application, I'm getting an XML Response and I'm trying to convert that XML Response using XmlNode.

My XML File : File

The XML Content will be like :

<account name="santosh@mx.omit-solutions.com" id="876e6b55-5a9c-44ff-a418-af737c47d2af">
  <a n="mobile">91 998977245009</a>
  <a n="zimbraMailDeliveryAddress">santosh@mx.omit-solutions.com</a>
  <a n="zimbraPrefIMLogChats">TRUE</a>
</account>
<account name="mani@mx.omit-solutions.com" id="ce91d3bf-83b8-4a55-a92e-2e080fa4a21b">
  <a n="zimbraMailDeliveryAddress">mani@mx.omit-solutions.com</a>
  <a n="zimbraPrefShowSearchString">FALSE</a>
  <a n="zimbraPrefIMLogChats">TRUE</a>
</account>

Here I'm showing two sample accounts from that XML Response and I need to loop through all the account nodes and get the zimbraMailDeliveryAddress which will be surely available in every node and also mobile element value ('91 998977245009') which may not be available in every node(i.e. the tag wont be available at all).

Is there a way to get these values?

I've tried using the XmlNamespaceManager like this :

XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
mgr.AddNamespace("bc", "urn:zimbraAdmin");
XmlNode result = doc.SelectSingleNode("//bc:account", mgr);
if (result != null)
{
    Console.WriteLine("Found {0}.", result.InnerText);
}
else
{
    // handle case that no element was found
    Console.WriteLine("No element found.");
}

But by using this code, I'm getting only first account node data and I'm unable to loop through all account nodes.

Can anyone please help me?


Solution

  • I'd suggest ditching XmlDocument and XPath and using LINQ to XML instead:

    var doc = XDocument.Parse(xml);
    
    XNamespace ns = "urn:zimbraAdmin";
    
    foreach (var account in doc.Descendants(ns + "account"))
    {
        var mobile = (string)account.Elements(ns + "a")
            .SingleOrDefault(e => (string)e.Attribute("n") == "mobile");
    
        var address = (string)account.Elements(ns + "a")
            .SingleOrDefault(e => (string)e.Attribute("n") == "zimbraMailDeliveryAddress");
    }
    

    See a working demo using your file here: https://dotnetfiddle.net/UOV40v