c# XElement解析xml文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/muxiong0308/article/details/79945640

先说下背景:统一采集平台每天会从网管采集各种配置文件、网络数据等信息,并以xml文件形式保存在ftp下。


再说下工作安排:领导想将每天的采集到的网络拓扑连接信息(即网元A的某端口,有一条连纤,连接至网元B的某端口)保存在数据库里,即解析xml文件并导入数据库。



        每天采集到的网络拓扑连接信息xml文件,即TopologicalLink.xml,里边大概长这样:

<DATA>
  <TOPOLOGICALLINK>
   </TOPOLOGICALLINK>
  <TOPOLOGICALLINK>
   </TOPOLOGICALLINK>
</DATA>

        整个xml文档由多个TopologicalLink元素构成,每个TopologicalLink展开里面大概长下边这样。里边除了各个字段,如userLabel、nativeEMSName这类的之外,注意到还有name这一种,就是里边由item元素组成,每一个item里只有name和value两个元素。

<?xml version="1.0" encoding="GBK"?>
<DATA>
   <TOPOLOGICALLINK>
     <name>
       <item>
         <name>EMS</name>
         <value>AN-U2000-4-P</value>
         </item>
       <item>
        <name>TopologicalLink</name>
        <value>2009-09-23 02:26:32 - 3661</value>
        </item>
      </name>
    <userLabel></userLabel>
    <nativeEMSName>f-10</nativeEMSName>
    <owner></owner>
    <direction>BI</direction>
    <rate>20</rate>
    <aEnd>
      <item>
        <name>EMS</name>

        查看了一下xml基础知识,在网上找到个DataSet.readxml来试了一下,发现read出来的table结构没看懂,且一些dataTable下的数据是空的。


        后来看到了XElement,觉得操作很方便。顺便想着到时候将每一个TopologicalLink输出为字典dic,再转换为dt导入数据库,所以解析这个TopologicalLink.xml的基本思路就是(伪代码)

xml=XElement.Load(xmlFilePath)
 foreach(每一个TopologicalLink in xml)
{
    foreach(TopologicalLink的每一个子代元素ele)
    {
        if(ele的子代里有item元素)
        {
            key=ele元素名+item子代name元素的值;
            value=item子代value元素的值
        }
        else
        {
             key=ele元素名;
             value=ele元素的值;
        }
        dic.Add(key,value)
    }
}

        代码主要部分如下:

IEnumerable<XElement> MatchElements = from temp in loadxml.Elements("TOPOLOGICALLINK")
                                          select temp;
Dictionary<string, string> dic = new Dictionary<string, string>();
 //步骤2
 //遍历每一个TOPOLOGICALLINK元素
 foreach (var MatchEle in MatchElements)
 {
     //步骤3
     IEnumerable<XElement> eleInMatchEle = MatchEle.Elements();
     foreach (XElement ele in eleInMatchEle)
     { 
         IEnumerable<XElement> items = from temp in ele.Elements("item")
      select temp;
         //步骤4         
         if (items.Count() > 0)
         {
              foreach (var item in items)
              {
                  strKey = ele.Name.ToString() + "_" + item.Element("name").Value.ToString();
                  strValue = item.Element("value").Value.ToString();
                  if (dic.ContainsKey(strKey) == false)
                  {
                       dic.Add(strKey, strValue);
                  }
               }
         }
         // 步骤5
         else
         {
             strKey = ele.Name.ToString();
             strValue = ele.Value.ToString();
             if (dic.ContainsKey(strKey) == false)
             {
                 dic.Add(strKey, strValue);
             }
         }
     }
     // 清空字典,准备下一个TOPOLOGICALLINK
     dic.Clear();
 }

        输出到控制台看一下一个TopologicalLink元素能解析成啥样,通过下边的代码来看输出的结果:

Console.WriteLine("------{0}-------", dic.Count);
foreach (string key in dic.Keys)
{
        Console.WriteLine("【{0}】{1}", key, dic[key]);
}
Console.WriteLine();
Console.ReadKey();

输出结果:

        这样对于TopologicalLink.xml的解析就妥了~

        但好景不长,领导后续的需求也暴露出了当前解析代码的不足,具体有以下几点:

  1. load整个文件。当前代码是直接load文件到内存,TopologicalLink才10M不到,后边还有2G的xml文件;

  2. 代码专用了。TopologicalLink最深也就3层就到item元素了,当前代码赤裸裸的只下钻了2层,后续领导又提出了好几块网络数据的xml也要做处理,难道每种xml文件写一个解析?

  3. 存在多个同名元素。如果有同名元素怎么办,比如后续会有隧道路由表,里边各条隧道的跳数(即经过的网元数)是不同的,每一跳都用一个IpCrossConnection元素做记录,一条隧道经过的全部IpCrossConnection又保存在一个IpCrossConnectionList下;


走着瞧呗,逢山开路遇水搭桥了。


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页