如何在.net中读取具有不同层次结构的xml文件 [英] How to read xml file having different hierarchy in .net

查看:88
本文介绍了如何在.net中读取具有不同层次结构的xml文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个7GB的xml大文件,我在这里粘贴了一小部分

I have big 7GB xml file ,and i am pasting small portion here

       <?xml version="1.0" encoding="UTF-8"?>
    <bulkFile xmlns:un="utranNrm.xsd"
        xmlns:es="Attributes.15.25.xsd"
        xmlns:xn="generic.xsd" xmlns:gn="geran.xsd" xmlns="configData.xsd">
      <fileHeader fileFormatVersion="32.615 V4.5" Name="Wmart"/>
      <configData dnPrefix="Undefined">
        <xn:SubNetwork id="M_ROOT">
          <xn:VsDataContainer id="1">
            <xn:attributes>
              <xn:vsDataType>vsDataAreas</xn:vsDataType>
              <xn:vsDataFormatVersion>SpecificAttributes</xn:vsDataFormatVersion>
              <es:vsDataAreas/>
            </xn:attributes>
            <xn:VsDataContainer id="424_2_2">
              <xn:attributes>
                <xn:vsDataType>vsDataPlmn</xn:vsDataType>
                <xn:vsDataFormatVersion>SpecificAttributes</xn:vsDataFormatVersion>
                <es:vsDataPlmn>
                  <es:userLabel></es:userLabel>
                  <es:mcc>424</es:mcc>
                  <es:mnc>2</es:mnc>
                  <es:mncLength>2</es:mncLength>
                  <es:aliasPlmnIdentities>
                    <es:mcc>424</es:mcc>
                    <es:mnc>2</es:mnc>
                    <es:mncLength>2</es:mncLength>
                  </es:aliasPlmnIdentities>
                </es:vsDataPlmn>
              </xn:attributes>
              <xn:VsDataContainer id="10">
                <xn:attributes>
                  <xn:vsDataType>vsDataLocationArea</xn:vsDataType>
                  <xn:vsDataFormatVersion>SpecificAttributes</xn:vsDataFormatVersion>
                  <es:vsDataLocationArea>
                    <es:userLabel></es:userLabel>
                    <es:lac>10</es:lac>
                    <es:t3212>10</es:t3212>
                    <es:att>1</es:att>
                  </es:vsDataLocationArea>
                </xn:attributes>
              </xn:VsDataContainer>
            </xn:VsDataContainer>
          </xn:VsDataContainer>
          <xn:SubNetwork id="G-Mum">
            <xn:attributes>
              <xn:userDefinedNetworkType>SiteSolutions</xn:userDefinedNetworkType>
              <xn:userLabel>G-Mum</xn:userLabel>
            </xn:attributes>
            <xn:MeContext id="32509_I_East">
              <xn:VsDataContainer id="23502_I_AAN_UAEU_Crescent_East">
                <xn:attributes>
                  <xn:vsDataType>vsDataMeContext</xn:vsDataType>
                  <xn:vsDataFormatVersion>EricssonSpecificAttributes.15.25</xn:vsDataFormatVersion>
                  <es:vsDataMeContext>
                    <es:userLabel>23502_I_AAN_UAEU_Crescent_East</es:userLabel>
                    <es:ipAddress>10.235.20.10</es:ipAddress>
                    <es:neMIMversion>vF.1.108</es:neMIMversion>
                    <es:lostSynchronisation>SYNCHRONISED</es:lostSynchronisation>
                    <es:bcrLastChange>1474785017888</es:bcrLastChange>
                    <es:bctLastChange>1470699087457</es:bctLastChange>
                    <es:multiStandardRbs6k>false</es:multiStandardRbs6k>
                    <es:mixedModeRadio>false</es:mixedModeRadio>
                    <es:mirrorMIBversion>F.1.100.S.1.6</es:mirrorMIBversion>
                    <es:stnNodes></es:stnNodes>
                  </es:vsDataMeContext>
                </xn:attributes>
              </xn:VsDataContainer>
              <xn:ManagedElement id="1">
                <xn:attributes>
                </xn:attributes>
                <xn:VsDataContainer id="1">
                  <xn:attributes>
                    <xn:vsDataType>vsDataManagedElement</xn:vsDataType>
                    <xn:vsDataFormatVersion>Attributes.15.25.xsd</xn:vsDataFormatVersion>
                    <es:vsDataManagedElement>
                      <es:siteRef>SubNetwork=M_ROOT,Site=32509_I_East</es:siteRef>
                      <es:productType>Node</es:productType>
                      <es:productName>RBS6601L</es:productName>
                      <es:productNumber></es:productNumber>
                      <es:productRevision></es:productRevision>
                      <es:prodDesignation>0</es:prodDesignation>
                    </es:vsDataManagedElement>
                  </xn:attributes>
                </xn:VsDataContainer>
                .
                .
                <xn:VsDataContainer id="1">
                  <xn:attributes>
                    <xn:vsDataType>vsDataENodeBFunction</xn:vsDataType>
                    <xn:vsDataFormatVersion>Attributes.15.25.xsd</xn:vsDataFormatVersion>
                    <es:vsDataENodeBFunction>
                      <es:userLabel></es:userLabel>
                      <es:dscpLabel>24</es:dscpLabel>
                      <es:dnsLookupOnTai>1</es:dnsLookupOnTai>
                      <es:eNBId>32509</es:eNBId>
                    </es:vsDataENodeBFunction>
                  </xn:attributes>
                  <xn:VsDataContainer id="BC_3250_32509_L1_B">
                    <xn:attributes>
                      <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>
                      <es:earfcndl>1651</es:earfcndl>
                      <es:earfcnul>19651</es:earfcnul>
                    </xn:attributes>
                  </xn:VsDataContainer>
                  ..
                  <xn:VsDataContainer id="BD_4250_32509_L1_B">
                    <xn:attributes>
                      <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>
                      <es:earfcndl>1651</es:earfcndl>
                      <es:earfcnul>19651</es:earfcnul>
                    </xn:attributes>
                  </xn:VsDataContainer>

                  <xn:VsDataContainer id="CC_3250_32509_L1_C">
                    <xn:attributes>
                      <xn:vsDataType>testranCellFDD</xn:vsDataType>
                      <es:earfcndl>165</es:earfcndl>
                      <es:earfcnul>19651</es:earfcnul>
                    </xn:attributes>
                  </xn:VsDataContainer>
                </xn:VsDataContainer>
                ..

              </xn:ManagedElement>
            </xn:MeContext>
 <xn:MeContext id="32509_I_west">
          <xn:VsDataContainer id="32509_I_AAN_UAEU_Crescent_East">
            <xn:attributes>
              <xn:vsDataType>vsDataMeContext</xn:vsDataType>
              <xn:vsDataFormatVersion>Attributes.15.25</xn:vsDataFormatVersion>
              <es:vsDataMeContext>
                <es:userLabel>32509_I_AAN_UAEU_Crescent_East</es:userLabel>
                <es:ipAddress>10.235.20.10</es:ipAddress>
                <es:neMIMversion>vF.1.108</es:neMIMversion>
                <es:lostSynchronisation>SYNCHRONISED</es:lostSynchronisation>
                <es:bcrLastChange>1474785017888</es:bcrLastChange>
                <es:bctLastChange>1470699087457</es:bctLastChange>
                <es:multiStandardRbs6k>false</es:multiStandardRbs6k>
                <es:mixedModeRadio>false</es:mixedModeRadio>
                <es:mirrorMIBversion>F.1.100.S.1.6</es:mirrorMIBversion>
                <es:stnNodes></es:stnNodes>
              </es:vsDataMeContext>
            </xn:attributes>
          </xn:VsDataContainer>
          <xn:ManagedElement id="1">
            <xn:attributes>
            </xn:attributes>
            <xn:VsDataContainer id="1">
              <xn:attributes>
                <xn:vsDataType>vsDataManagedElement</xn:vsDataType>
                <xn:vsDataFormatVersion>Attributes.15.25.xsd</xn:vsDataFormatVersion>
                <es:vsDataManagedElement>
                  <es:siteRef>SubNetwork=M_ROOT,Site=32509_I_East</es:siteRef>
                  <es:productType>Node</es:productType>
                  <es:productName>RBS6601L</es:productName>
                  <es:productNumber></es:productNumber>
                  <es:productRevision></es:productRevision>
                  <es:prodDesignation>0</es:prodDesignation>
                </es:vsDataManagedElement>
              </xn:attributes>
            </xn:VsDataContainer>
            .
            .
            <xn:VsDataContainer id="1">
              <xn:attributes>
                <xn:vsDataType>vsDataENodeBFunction</xn:vsDataType>
                <xn:vsDataFormatVersion>Attributes.15.25.xsd</xn:vsDataFormatVersion>
                <es:vsDataENodeBFunction>
                  <es:userLabel></es:userLabel>
                  <es:dscpLabel>24</es:dscpLabel>
                  <es:dnsLookupOnTai>1</es:dnsLookupOnTai>
                  <es:eNBId>32509</es:eNBId>
                </es:vsDataENodeBFunction>
              </xn:attributes>
              <xn:VsDataContainer id="CC_3250_32509_L1_B">
                <xn:attributes>
                  <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>
                  <es:earfcndl>1651</es:earfcndl>
                  <es:earfcnul>19651</es:earfcnul>
                </xn:attributes>
              </xn:VsDataContainer>
              ..
              <xn:VsDataContainer id="CD_4250_32509_L1_B">
                <xn:attributes>
                  <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>
                  <es:earfcndl>1651</es:earfcndl>
                  <es:earfcnul>19651</es:earfcnul>
                </xn:attributes>
              </xn:VsDataContainer>

              <xn:VsDataContainer id="DC_3250_32509_L1_C">
                <xn:attributes>
                  <xn:vsDataType>testranCellFDD</xn:vsDataType>
                  <es:earfcndl>165</es:earfcndl>
                  <es:earfcnul>19651</es:earfcnul>
                </xn:attributes>
              </xn:VsDataContainer>
            </xn:VsDataContainer>
            ..

          </xn:ManagedElement>
        </xn:MeContext>
          </xn:SubNetwork>

        </xn:SubNetwork>
      </configData>
    </bulkFile>

在这里,我想获取声明的c#变量的值,这些值类似于subnetworksitenameeNBIdcellnameearfcndlearfcnul 所有信息都驻留在根标记<xn:SubNetwork id="M_ROOT">标记下,其余所有归根目录下的所有站点所有,这里我仅粘贴一个站点详细信息.逻辑为

Here i want to get values for c# variables i declared which are like subnetwork,sitename,eNBId,cellname,earfcndl and earfcnul all the information's resides under root tag <xn:SubNetwork id="M_ROOT"> tag,rest all for all sites coming under the root and here i am pasting only one site details.The logic is

   subnetwork = <xn:SubNetwork id > attribute value
    sitename  =  <xn:MeContext id> attribute value
    eNBId =  <es:eNBId> value, here the important thing is, there will be huge number of `<xn:VsDataContainer id="1">` parent tag,but the filtration is based on `<xn:vsDataType>` inner tag which is of `vsDataENodeBFunction`.
    cellname = `<xn:VsDataContainer id>` attribute value and 
    `earfcndl` and `earfcnul` is values for `<es:earfcndl> and         <es:earfcnul>` tag .Here also filtration is based on      <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>

所以我想得到subnetwork = G-Mum,,sitename = 32509_I_East,,eNBId=32509,,cellname=BC_3250_32509_L1_B,,earfcndl=1651,,earfcnul=19651.

我在这里执行了以下代码,但是卡住了,不知道该怎么办.但是我可以保证这是唯一的方法(xmlreader(XElement)XNode.ReadFrom方法),我们可以读取7Gb Xml文件,其余全部将抛出内存不足异常"

Here i did following code, but got stuck and don't know what to do.But i can guarantee that this is the only way(xmlreader and (XElement)XNode.ReadFrom method) we can read 7Gb Xml file,rest all will throw "Out of memory exceptions"

using (XmlReader xr = XmlReader.Create(path))
                {
                    xr.MoveToContent();
                    XNamespace un = xr.LookupNamespace("un");
                    while (xr.Read())
                    {
                        while (xr.NodeType == XmlNodeType.Element && xr.NamespaceURI == un && xr.LocalName == "M_ROOT")
                        {
                            XElement pin = (XElement)XNode.ReadFrom(xr);
                            var data = from atts in pin.Elements(un + "attributes")
                                       select new
                                       {
                                           eNBId= (string)atts.Element(es + "eNBId"),

                                       }
                        }
                    }

编辑 层次结构只是一个xn:SubNetwork id ="M_ROOT"标签,其中包含所有区域,例如再次包含所有站点信息的under标签,而该标签又包含所有vsinfoEUtranCellFDD类型的单元格信息

EDIT Hierarchy is only one xn:SubNetwork id="M_ROOT" tag which contain all the regions like which again contains all the site information's under tag which again contains all the cell information's under of type vsDataEUtranCellFDD

编辑 @jdweng感谢您的帮助,现在他们又增加了xml,现在又增加了我们使用(XElement)XElement.ReadFrom(reader)获取的摘录xml.本身会抛出内存不足"异常.如何删除不必要的xml部分.我的层次结构是

EDIT @jdweng thanks for your help,now they have increased xml again,and now the snippet xml which we took by using the(XElement)XElement.ReadFrom(reader); itself throwing the Out of memory exception.How can i remove the unnecessary xml part.My hierarchy is

<xn:SubNetwork id="M_ROOT">--------------Root
      <xn:SubNetwork id="G-Mum">---------Region
              <xn:MeContext id="32509_I_East">-----sites
                     <xn:VsDataContainer id="BC_3250_32509_L1_B"> ---Cells
                          <xn:attributes>
                            <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>
                    </xn:MeContext>
                  </xn:SubNetwork>
                </xn:SubNetwork>

所以我在我的问题的恳求中发布的都是必要的数据,请保留所有不必要的

SO what ever i posted on the very begging of my question is necessary data,rest all unnecessary

编辑 @jdweng,是的,我张贴的是必填项,我正在再次编辑我的问题. 层次结构是

EDIT @jdweng ,yes what ever i posted is the required on,I am editing my question again. Heirarchy is

`<xn:SubNetwork>`          --------Root  and only one 

然后几行 <xn:SubNetwork>包含地区将成组出现,但是这里只有id以G-开头是有效的,因此在这里G-Mum 然后<xn:MeContext>包含站点的站点将以组的形式出现,该站点又包含很多<xn:VsDataContainer>,但是此处包含子节点<xn:vsDataType>vsDataManagedElement</xn:vsDataType>的站点是有效的,以便获得<es:eNBId>. 然后在子节点<xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>的几行<xn:VsDataContainer>包含单元格之后再次出现.this(cells)是最里面的一个. 因此将会有大量的<xn:VsDataContainer>出现,其中只有用于导入Enbid的子节点<xn:vsDataType>vsDataENodeBFunction</xn:vsDataType>和用于导入单元格的<xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType>子节点

Then after several line <xn:SubNetwork> contain Regions will come as groups,But here only id begins with G- is valid so here G-Mum Then <xn:MeContext> contains sites will come as groups which again contains lot of <xn:VsDataContainer>,but here one contains child node <xn:vsDataType>vsDataManagedElement</xn:vsDataType> is valid one in order to get <es:eNBId>. Then again after several lines <xn:VsDataContainer> of child nodes <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType> contains cells will come.This(cells) is the inner most one. SO there will be huge number of <xn:VsDataContainer> will come,out of it only of child nodes <xn:vsDataType>vsDataENodeBFunction</xn:vsDataType> for getting Enbid and <xn:vsDataType>vsDataEUtranCellFDD</xn:vsDataType> for cells are import

编辑 在分析了大文件之后,我知道单元格位于站点下,但是我将其张贴在外面,即vsDataEUtranCellFDD处于标签vsDataENodeBFunction下.我编辑了我发布的xml

EDIT After analyzing big file i came to know that cells are coming under sites ,but i posted it in out side,Ie vsDataEUtranCellFDD is coming under the tag vsDataENodeBFunction.I have edited my xml which i posted

修改10/10/16 xml几乎没有变化,在<xn:vsDataType>vsDataENodeBFunction</xn:vsDataType>VsDataContainer之前还有一个VsDataContainer,由于未捕获vsDataENodeBFunction.我使用了Skip(1)但没有用 vsDataManagedElement

EDIT 10/10/16 There is little change in xml ,one more VsDataContainer was there before VsDataContainer of <xn:vsDataType>vsDataENodeBFunction</xn:vsDataType>,Due to that vsDataENodeBFunction is not caught.I used Skip(1) but didn't work vsDataManagedElement

推荐答案

您的文件很大,因此最好使用XmlReader.试试这个代码

You have a very large file so it is best to use XmlReader. Try this code

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

namespace ConsoleApplication16
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        enum State
        {
            GET_SUBNETWORK,
            GET_MECONTEXT,
            GET_CONTAINERS,
            GET_SUBNETWORK_OR_MECONTEXT
        }
        static void Main(string[] args)
        {
            XmlReaderSettings settings = new XmlReaderSettings() { IgnoreWhitespace = true };
            XmlReader reader = XmlReader.Create(FILENAME, settings);

            reader.ReadToFollowing("SubNetwork", "generic.xsd");
            Network.network.name = reader.GetAttribute("id");
            Network.network.subnetworks = new List<SubNetwork>();

            string xnNameSpace = reader.LookupNamespace("xn");
            reader.ReadToFollowing("SubNetwork", xnNameSpace);

            Sites newSite = null;
            SubNetwork subNetWork = null;
            Boolean endElement = false;

            State state = State.GET_SUBNETWORK;
            while (!reader.EOF)
            {
                switch (state)
                {
                    case State.GET_SUBNETWORK:
                        if (reader.Name != "xn:SubNetwork")
                        {
                            reader.ReadToFollowing("SubNetwork", xnNameSpace);
                        }
                        if (!reader.EOF)
                        {
                            subNetWork = new SubNetwork();
                            Network.network.subnetworks.Add(subNetWork);
                            subNetWork.name = reader.GetAttribute("id");
                            subNetWork.sites = new List<Sites>();

                            state = State.GET_MECONTEXT;
                        }
                        break;

                    case State.GET_MECONTEXT :
                        if (reader.Name != "xn:MeContext")
                        {
                            if (reader.NodeType == XmlNodeType.EndElement)
                            {
                                endElement = true;
                                state = State.GET_SUBNETWORK;
                            }
                            else
                            {
                                endElement = false;
                                reader.ReadToFollowing("MeContext", xnNameSpace);
                            }
                        }
                        if (!reader.EOF && !endElement)
                        {
                            state = State.GET_CONTAINERS;
                            newSite = new Sites();
                            subNetWork.sites.Add(newSite);
                            newSite.sitename = reader.GetAttribute("id");
                            reader.ReadToFollowing("ManagedElement", xnNameSpace);
                            reader.ReadToFollowing("VsDataContainer", xnNameSpace);
                        }
                        break;

                    case State.GET_CONTAINERS:

                        if (!reader.EOF)
                        {
                            switch (reader.NodeType)
                            {
                                case XmlNodeType.EndElement:
                                    state = State.GET_SUBNETWORK_OR_MECONTEXT;
                                    break;
                                case XmlNodeType.Text:
                                    string text = reader.ReadContentAsString();
                                    break;

                                case XmlNodeType.Element:

                                    string elementName = reader.Name;
                                    XElement element = (XElement)XElement.ReadFrom(reader);
                                    if (elementName == "xn:VsDataContainer")
                                    {
                                        XElement vsDataENodeBFunction = element.Descendants().Where(a => a.Name.LocalName == "vsDataENodeBFunction").FirstOrDefault();
                                        if (vsDataENodeBFunction != null)
                                        {                                            
                                            XElement eNBId = element.Descendants().Where(a => a.Name.LocalName == "eNBId").FirstOrDefault();
                                            if (eNBId != null)
                                            {
                                                newSite.eNBId = (int)eNBId;
                                            }
                                        }
                                        List<XElement> vsDataContainers = element.Descendants().Where(a => a.Name.LocalName == "VsDataContainer").ToList();
                                        List<XElement> vsDataEUtranCellFDD = vsDataContainers.Where(x => x.Descendants().Where(a => (a.Name.LocalName == "vsDataType") && ((string)a == "vsDataEUtranCellFDD")).Any()).ToList();
                                        if (vsDataEUtranCellFDD.Any())
                                        {
                                            List<CellName> cells = vsDataEUtranCellFDD.Select(x => new CellName()
                                            {
                                                id = (string)x.Attribute("id"),
                                                earfcndl = (int)x.Descendants().Where(a => a.Name.LocalName == "earfcndl").FirstOrDefault(),
                                                earfcnul = (int)x.Descendants().Where(a => a.Name.LocalName == "earfcnul").FirstOrDefault()
                                            }).ToList();
                                            if (newSite.cellName == null)
                                            {
                                                newSite.cellName = new List<CellName>();
                                            }
                                            newSite.cellName.AddRange(cells);
                                        }
                                    }
                                    break;

                                default:
                                    Console.WriteLine("Unexpected Results");
                                    string elementText = reader.ReadContentAsString();
                                    Console.ReadLine();
                                    break;
                            }
                        }
                        break;

                    case State.GET_SUBNETWORK_OR_MECONTEXT :
                        switch(reader.NodeType)
                        {
                            case XmlNodeType.Element :
                                switch(reader.Name)
                                {
                                    case "xn:MeContext" :
                                        state = State.GET_MECONTEXT;
                                        break;
                                    case "xn:SubNetwork" :
                                        state = State.GET_SUBNETWORK;
                                        break;
                                    default :
                                        reader.ReadStartElement();
                                        break;
                                }
                                break;

                            case XmlNodeType.Text:
                                string text = reader.ReadContentAsString();
                                break;

                            case XmlNodeType.EndElement:
                                reader.ReadEndElement();
                                break;

                            default:
                                Console.WriteLine("Unexpected Results");
                                string elementText = reader.ReadContentAsString();
                                Console.ReadLine();
                                break;

                        }
                        break;
                }
            }
        }

    }
    public class Network
    {
        public static Network network = new Network();
        public string name { get; set; }
        public List<SubNetwork> subnetworks { get; set; }
    }
    public class SubNetwork
    {
        public string name { get; set; }
        public List<Sites> sites { get; set; }

    }
    public class Sites
    {
        public string sitename { get; set; }
        public int eNBId { get; set; }
        public List<CellName> cellName { get; set; }
    }
    public class CellName
    {
        public string id { get; set; }
        public int earfcndl { get; set; }
        public int earfcnul { get; set; }
    }
}

这篇关于如何在.net中读取具有不同层次结构的xml文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆