在.NET中处理xml文件需要花费大量时间

问题描述 投票:1回答:1

我有一个XML文件,其中数据分散。我必须得到位于XML标签<managedObject class="JTS"下的所有单元格值,分散在XML标签<managedObject class="CCF"上的依赖站点信息,以及其他依赖的幂函数分散在XML标签<managedObject class="POC"上。我正在使用XmlReader.ReadFrom来处理小部分和处理,但现在问题是XML对于每个单元格,站点和电源信息都很重要,为此我每次都在阅读整个大型XML文件,这是错误的逻辑和服用很多时间。有没有什么方法可以将所有单元格(比如5000个单元格)加载到类和相应的站点中,为单元格中的单元格所需的信息提供动力,然后使用foreach迭代处理类。我使用的代码和XML片段如下所示

<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>

和代码

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;

}

这里我在XML片段中有两个单元格PLMN-PLMN/BSC-404500/BTS-123PLMN-PLMN/BSC-404501/BTS-123,像这样我有5000个单元格

<?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>
c# xml linq oop console-application
1个回答
1
投票

我使用了XmlReader和Xml Linq的组合。下面的代码将元素放入字典中。

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);
                    }
                }
            }
        }
    }
}

这是我使用的xml

?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>
© www.soinside.com 2019 - 2024. All rights reserved.