zoukankan      html  css  js  c++  java
  • LinqToXml高级用法介绍

    一、函数构造

    什么是函数构造?其是指通过单个语句构建XML树的能力。

    那么它有什么作用呢?

    作用1、用单个表达式快速创建复杂的XML树

    见实例代码CreateXml( ):

    public static XElement CreateXml()
            {
                XElement emp = new XElement("Employees",
                    new XElement("Employee",new XAttribute("id","1"),
                                               new XAttribute("Dept","00001"),
                                               new XElement("name","Scott"),
                                               new XElement("Address",
                                                   new XElement("Street","555 main st."),
                                                   new XElement("City","Wellington"),
                                                   new XElement("State","FL"),
                                                   new XElement("Zip","33144")
                                                   ),
                                               new XElement("Title","All things Techy"),
                                               new XElement("HireDate","02/05/2007"),
                                               new XElement("Gender","M")
                        )
                    );
                return emp;
            }

    输出结果:

    <Employees>
      <Employee id="1" Dept="00001">
        <name>Scott</name>
        <Address>
          <Street>555 main st.</Street>
          <City>Wellington</City>
          <State>FL</State>
          <Zip>33144</Zip>
        </Address>
        <Title>All things Techy</Title>
        <HireDate>02/05/2007</HireDate>
        <Gender>M</Gender>
      </Employee>
    </Employees>

    作用2、通过查询表达式容易地控制所构建的XML树,更方便的修改和保存XML树。

    见实例代码EditXml( )

    public static XElement EditXml()
            {
                XElement emp = XElement.Load(@"output.xml");
                emp = new XElement("Employee",
                           emp.Element("Employee").Element("name"),
                           from atts in emp.Element("Employee").Attributes() where atts.Name == "id" select new XElement(atts.Name, (string)atts)
                         );
                return emp;
            }

    输出结果:

    <Employee>
      <name>Scott</name>
      <id>1</id>
    </Employee>

    二、批注

    什么是批注?

    批注是与一段文本相关联的说明性的注释。但批注是不可见的

    实例代码AddAnnotation( ):

    public static XElement AddAnnotation()
            {
                _2Annotation anno = new _2Annotation(5);
                XElement root = XElement.Load("output.xml");
                root.AddAnnotation(anno);
                root.AddAnnotation("批注:1");
                root.AddAnnotation("批注:2");
                //批注不可见,但可通过下面这种方式获取批注值
                _2Annotation newAnno = root.Annotation<_2Annotation>();
                Console.WriteLine("批注值:" + newAnno.Val1);
                IEnumerable<string> stringList = root.Annotations<string>();
                foreach (string item in stringList)
                {
                    Console.WriteLine(item);
                }
    
                return root;
            }

    输出结果:

    批注值:5
    批注:1
    批注:2

    三、轴

    Linq To Xml轴是干什么用的?

    在一个xml数中遍历并返回多个节点的值。其返回元素和属性的集合。

    轴的实现方法有哪些呢

    方法1:Ancestors

    其返回指定节点的上级元素的集合

    见代码Ancestors():

    private XElement _XmlE;
            public _3Zhou()
            {
                _XmlE = new XElement("Employees",
                      new XElement("Employee",
                             new XElement("Name",
                                 new XElement("FirstName", "Gong"),
                                 new XElement("MiddleName", "Wen"),
                                 new XElement("LastName", "Tao")
                                 ),
                             new XElement("Sex", "")
                           ),
                    new XElement("Employee",
                          new XElement("Name",
                              new XElement("FirstName", "Zhao"),
                              new XElement("MiddleName", "Si"),
                              new XElement("LastName", "Si")
                              ),
                         new XElement("Sex", "Girl")
                              )
                     );
            }
            public IEnumerable<XElement> Ancestors()
            {
                return _XmlE.Elements("Employee").Elements("Name").Ancestors<XElement>();
            }

    见输出:

    QQ截图20130825105650

    同时它还包含一个重载方法,即Ancestors(XName name), name是使集合只返回指定name的元素。

    见代码Ancestors(string xname):

    public IEnumerable<XElement> Ancestors(string xname)
            {
                return _XmlE.Elements("Employee").Elements("Name").Ancestors<XElement>(xname);
            }

    见输出:

    QQ截图20130825105914

    方法2:Descendants

    与Ancestors方法相反,其返回指定元素的后续元素的集合

    见代码:

    public IEnumerable<XElement> Descendants()
            {
                return _XmlE.Elements("Employee").Elements("Name").Descendants<XElement>();
            }

    见输出:

    QQ截图20130825105650

    它同时也包含一个重载方法Descendants(string xname),作用和Ancestors方法一样

    方法3:AncestorsAndSelf

    方法4:DescendantsAndSelf

    方法3和方法4同方法1和2,不过返回的集合中包含了自身元素而已。

    四、事件

    事件是指,当你对xml树进行修改时,linq to xml事件会提供通知。主要包含两个事件,一个是changing一个是changed,changing就是在改变之前触发,changed是改变之后触发。但如果是修改值得话,会触发两遍,因为这是一次删除和一次插入的操作。

    见代码:

    public _4Event()
            {
                _XmlE = new XElement("Employees",
                      new XElement("Employee",
                             new XElement("Name",
                                 new XElement("FirstName", "Gong"),
                                 new XElement("MiddleName", "Wen"),
                                 new XElement("LastName", "Tao")
                                 ),
                             new XElement("Sex", "")
                           ),
                    new XElement("Employee",
                          new XElement("Name",
                              new XElement("FirstName", "Zhao"),
                              new XElement("MiddleName", "Si"),
                              new XElement("LastName", "Si")
                              ),
                         new XElement("Sex", "Girl")
                              )
                     );
                _XmlE.Changing += _XmlE_Changing;
                _XmlE.Changed += _XmlE_Changed;
                _XmlE.Element("Employee").Elements("Name").Elements("FirstName").First().AddAfterSelf(new XElement("NickName", "taoGe"));
            }
    
            void _XmlE_Changed(object sender, XObjectChangeEventArgs e)
            {
                Console.WriteLine("changed event raised");
                XElement newEl = (XElement)sender;
                Console.WriteLine("Sender:" + newEl.Name);
                Console.WriteLine("Object Change:" + e.ObjectChange);
            }
    
            void _XmlE_Changing(object sender, XObjectChangeEventArgs e)
            {
                //    throw new NotImplementedException();
                Console.WriteLine("changing event raised");
                XElement newEl = (XElement)sender;
                Console.WriteLine("Sender:" + newEl.Name);
                Console.WriteLine("Object Change:" + e.ObjectChange);
            }

    见输出:

    QQ截图20130825110134

    五、流处理Xml文档

    这个主要用于处理大型xml文档和树的。因为大型xml文档会非常消耗内存。而流处理的工作原理是从xml源中读取一小片段数据,进行处理,从而减少内存的使用量。

    其具体实现是使用XmlReader类来快速遍历XML文档以寻找所需要的节点,然后调用ReadFrom方法从源读取信息并填充到目标xml片段。

    见代码:

    public static IEnumerable<XElement> StreamSalesOrders(string uri)
            {
                using (XmlReader reader = XmlReader.Create(uri))
                {
                    XElement name = null;
                    XElement order = null;
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element && reader.Name == "SalesPerson")
                        {
                            while (reader.Read())
                            {
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "Name")
                                {
                                    name = XElement.ReadFrom(reader) as XElement;
                                    break;
                                }
                            }
                            while (reader.Read())
                            {
                                if (reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                                if (reader.NodeType == XmlNodeType.Element && reader.Name == "Order")
                                {
                                    order = XElement.ReadFrom(reader) as XElement;
                                    if (order != null)
                                    {
                                        XElement tmpRoot = new XElement("TempRoot", new XElement(name));
                                        tmpRoot.Add(order);
                                        // yield return 提供了迭代器一个比较重要的功能,
                                            //即取到一个数据后马上返回该数据,不需要全部数据装入数列完毕,这样有效提高了遍历效率。
                                            yield return order;
                                    }
                                }
                            }
                        }
                    }
                }
            }

    见输出:

    QQ截图20130825114526

    源码下载:

    喜欢就动动手指点下推荐吧,您的支持是我分享的动力!

  • 相关阅读:
    国外物联网平台(8):Telit
    国外物联网平台(7):FogHorn
    国外物联网平台(6):Electric Imp
    国外物联网平台(5):Exosite Murano
    国外物联网平台(4):Ayla Networks
    国内物联网平台(8):中移物联网开放平台OneNet
    Backbone入门讲解
    underscore.js库的浅析
    Backbone框架浅析
    Handlebars模板库浅析
  • 原文地址:https://www.cnblogs.com/flowwind/p/3280636.html
Copyright © 2011-2022 走看看