peter
peter

Reputation: 8682

Processing xml file taking lot of time in.net

I have an XML file where data is scattered over. I have to get all cells value which reside in under XML tag <managedObject class="JTS", dependent site information scattered over XML tag <managedObject class="CCF", and other dependent power information are scattered over XML tag <managedObject class="POC". I am using XmlReader.ReadFrom to take the small section and processing, but now the issue is the XML is big for each cell, site and power information, and for it I am reading the entire big XML file each time, which is bad logic and taking lot of time. Is there any way I can load all the cells(say 5000 cells) into classes and corresponding sites, power what ever information required for cells in to the classes and then process the classes by using foreach iteration. The code and XML snippet I am using is as below

<managedObject class="JTS" version="BSC17" distName="PLMN-PLMN/BSC-404500">
  <p name="name">VM_25261_G1_A</p>
  <p name="cellBarQualify">0</p>
  <p name="cellBarred">0</p>
  <p name="cId">25261</p>
  <p name="hoppingMode">1</p>
  <p name="hoppingSequenceNumber1">54</p>

  <managedObject class="CCF" version="BSC17" distName="PLMN-PLMN/BSC-404500">
    <p name="name">ET_AR_G_0267_GHABATGHAYATI</p>
    <p name="SBTSId">10267</p>
    <p name="abisInterfaceConnectionType">2</p>
    <p name="adminState">1</p>

    <managedObject class="POC" version="BSC17" distName="PLMN-PLMN/BSC-404500">
      <p name="alpha">0</p>
      <p name="bepPeriod">10</p>
      <p name="bsTxPwrMax">0</p>
      <p name="bsTxPwrMax1x00">0</p>

And the code

using (XmlReader xr = XmlReader.Create(path, settings))
{
    xr.MoveToContent();
    while (xr.Read())
    {
        while (xr.NodeType == XmlNodeType.Element && xr.LocalName == "managedObject" && xr.GetAttribute("class") == "JTS")
        {
            dist_name = xr.GetAttribute("distName");
            dist_name_ori = dist_name;
            XElement pin = (XElement)XNode.ReadFrom(xr);
            cell_name = GetValueForNokia(pin, "name");
            DataTable dtSiteDetails = GetSiteDetails2G(path, dist_name, settings);
            DataTable dtBasePowrDetails = GetBasePowrDetails2G(path, dist_name_ori, settings);


private static DataTable GetSiteDetails2G(string path, string cell_nametomatchwith_sitename, XmlReaderSettings settings)
{
    DataTable dt = null;

    try
    {
        using (XmlReader xr = XmlReader.Create(path, settings))
        {
            xr.MoveToContent();
            while (xr.Read())
            {
                while (xr.NodeType == XmlNodeType.Element && xr.LocalName == "managedObject" && xr.GetAttribute("class") == "CCF")
                {
                    distname = xr.GetAttribute("distName");
                    XElement pin = (XElement)XNode.ReadFrom(xr);
                    if (distname == cell_nametomatchwith_sitename)
                    {
                        DataRow dr = dt.NewRow();

                        dr[0] = xr.GetAttribute("version");
                        dr[1] = GetValueForNokia(pin, "name");
                        dt.Rows.Add(dr);
                        done = true;
                        break;
                    }
                    else
                        break;
                }
                if (done)
                    break;
            }
        }
    }
    catch (Exception)
    {

        throw;
    }
    return dt;
}

private static DataTable GetBasePowrDetails2G(string path, string cell_nametomatchwith_POC, XmlReaderSettings settings)
{

    try
    {
        dt = new DataTable();
        dt.Columns.Add("bsTxPwrMax");
        using (XmlReader xr = XmlReader.Create(path, settings))
        {
            xr.MoveToContent();
            while (xr.Read())
            {
                while (xr.NodeType == XmlNodeType.Element && xr.LocalName == "managedObject" && xr.GetAttribute("class") == "POC")
                {
                    distname = xr.GetAttribute("distName");

                    XElement pin = (XElement)XNode.ReadFrom(xr);
                    if (distname == cell_nametomatchwith_POC)
                    {
                        DataRow dr = dt.NewRow();

                        dr[0] = GetValueForNokia(pin, "bsTxPwrMax");
                        dt.Rows.Add(dr);
                        done = true;
                        break;
                    }
                    else
                        break;
                }
                if (done)
                    break;
            }
        }
    }
    catch (Exception)
    {

        throw;
    }
    return dt;
}

private static string GetValueForNokia(XElement pin, string input)
{
    XNamespace ns = "raml20.xsd";
    var output = pin.Descendants(ns + "p").FirstOrDefault(
        p => p.Attributes("name").FirstOrDefault(a => a.Value == input) != null
    );
    return output == null ? null : output.Value;

}

Here I have two cells PLMN-PLMN/BSC-404500/BTS-123 and PLMN-PLMN/BSC-404501/BTS-123 in XML snippet, like this I have 5000 cells

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <managedObject class="JTS" version="BSC17" distName="PLMN-PLMN/BSC-404500/BTS-123">
    <p name="name">VM_25261_G1_A</p>
    <p name="cellBarQualify">0</p>
    <p name="cellBarred">0</p>
    <p name="cId">25261</p>
    <p name="hoppingMode">1</p>
    <p name="hoppingSequenceNumber1">54</p>
  </managedObject>
.
.
  <managedObject class="CCF" version="BSC17" distName="PLMN-PLMN/BSC-404500">
    <p name="name">ET_AR_G_0267_GHABATGHAYATI</p>
    <p name="SBTSId">10267</p>
    <p name="abisInterfaceConnectionType">2</p>
    <p name="adminState">1</p>
  </managedObject>
.
.
  <managedObject class="POC" version="BSC17" distName="PLMN-PLMN/BSC-404500">
    <p name="alpha">0</p>
    <p name="bepPeriod">10</p>
    <p name="bsTxPwrMax">0</p>
    <p name="bsTxPwrMax1x00">0</p>
  </managedObject>

  <managedObject class="JTS" version="BSC17" distName="PLMN-PLMN/BSC-404501/BTS-123">
    <p name="name">VM_25262_G1_A</p>
    <p name="cellBarQualify">0</p>
    <p name="cellBarred">0</p>
    <p name="cId">25262</p>
    <p name="hoppingMode">1</p>
    <p name="hoppingSequenceNumber1">54</p>
  </managedObject>
.
.
  <managedObject class="CCF" version="BSC17" distName="PLMN-PLMN/BSC-404501">
    <p name="name">ET_AR_G_0267_GHABATGHAYATI</p>
    <p name="SBTSId">10267</p>
    <p name="abisInterfaceConnectionType">2</p>
    <p name="adminState">1</p>
  </managedObject>
.
.
  <managedObject class="POC" version="BSC17" distName="PLMN-PLMN/BSC-404501">
    <p name="alpha">0</p>
    <p name="bepPeriod">10</p>
    <p name="bsTxPwrMax">10</p>
    <p name="bsTxPwrMax1x00">0</p>
  </managedObject>
</root>

Upvotes: 1

Views: 82

Answers (1)

jdweng
jdweng

Reputation: 34433

I used a combination of XmlReader and Xml Linq. The code below puts elements into a dictionary.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication63
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            while (!reader.EOF)
            {
                if (reader.Name != "managedObject")
                {
                    reader.ReadToFollowing("managedObject");
                }
                if (!reader.EOF)
                {
                    XElement managedObject = (XElement)XElement.ReadFrom(reader);

                    ManagedObject newObject = new ManagedObject();
                    ManagedObject.objects.Add(newObject);

                    newObject.mClass = (string)managedObject.Attribute("class");
                    newObject.distName = (string)managedObject.Attribute("distName");
                    newObject.hierachy = newObject.distName.Split(new char[] { '/' });

                    newObject.objectdict = managedObject.Elements()
                        .GroupBy(x => (string)x.Attribute("name"), y => (string)y)
                        .ToDictionary(x => x.Key, y => y.FirstOrDefault());
                }
            }
            ManagedObjectNode.CreateTree();
        }
        public class ManagedObject
        {
            public static List<ManagedObject> objects = new List<ManagedObject>();

            public Dictionary<string, string> objectdict { get; set; }

            public string distName { get; set; }
            public string mClass { get; set; }

            public string[] hierachy { get; set; }
        }
        public class ManagedObjectNode
        {
            public static ManagedObjectNode root = new ManagedObjectNode();

            public Dictionary<string, ManagedObjectNode> children { get; set; }
            public List<ManagedObject> leaves { get; set; }
            public string nodeName { get; set; }

            public static void CreateTree()
            {
                root.nodeName = "root";
                GetTreeRecursive(root, ManagedObject.objects, 0);
            }
            public static void GetTreeRecursive(ManagedObjectNode parent, List<ManagedObject> mObjects, int level)
            {
                var groups = mObjects.GroupBy(x => x.hierachy[level]).ToList();
                foreach (var group in groups)
                {
                    ManagedObjectNode newNode = new ManagedObjectNode();
                    newNode.nodeName = group.Key;
                    if (parent.children == null) parent.children = new Dictionary<string, ManagedObjectNode>();
                    parent.children.Add(group.Key, newNode);
                    newNode.leaves = group.Where(x => x.hierachy.Count() - 1 == level).ToList();
                    List<ManagedObject> hasChildren = group.Where(x => x.hierachy.Count() - 1 > level).ToList();
                    if (hasChildren.Count() > 0)
                    {
                        GetTreeRecursive(newNode, hasChildren, level + 1);
                    }
                }
            }
        }
    }
}

Here is the xml I used

?xml version="1.0" encoding="utf-8" ?>
<root>
  <managedObject class="JTS" version="BSC17" distName="PLMN-PLMN/BSC-404500">
    <p name="name">VM_25261_G1_A</p>
    <p name="cellBarQualify">0</p>
    <p name="cellBarred">0</p>
    <p name="cId">25261</p>
    <p name="hoppingMode">1</p>
    <p name="hoppingSequenceNumber1">54</p>
  </managedObject>

  <managedObject class="CCF" version="BSC17" distName="PLMN-PLMN/BSC-404500">
    <p name="name">ET_AR_G_0267_GHABATGHAYATI</p>
    <p name="SBTSId">10267</p>
    <p name="abisInterfaceConnectionType">2</p>
    <p name="adminState">1</p>
  </managedObject>

  <managedObject class="POC" version="BSC17" distName="PLMN-PLMN/BSC-404500">
    <p name="alpha">0</p>
    <p name="bepPeriod">10</p>
    <p name="bsTxPwrMax">0</p>
    <p name="bsTxPwrMax1x00">0</p>
  </managedObject>
</root>

Upvotes: 1

Related Questions