我有一个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-123
和PLMN-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>
答案 0 :(得分: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>