• C# ~ 从 XML 到 Linq 到 Linq to XML


    可扩展标记语言 (Extensible Markup Language), 标记 (markup) 是关键部分,是标准通用标记语言 (Standard Generalized Markup Language,SGML) 的子集,一种简单的存储和提取数据的文本格式。

    XML数据分层组织,主要用于传输和存储数据,而HTML主要用于显示数据。.

    XML文件由内容标记组成,具体地: 

    • 文档类型定义 (Document Type Definition,DTD),规定文档的逻辑结构;
    • 可扩展的样式语言(Extensible Style Language,XSL),规定XML文档样式;
    • 可扩展链接语言 (Extensible Link Language,XLL),支持Web上已有的简单链接; 

    XML结构化数据,解决了不同平台系统间数据结构/模式的差异。

    XML文档用XML声明、XML名称空间、XML元素和特性构建。声明定义XML版本,名称空间定义词汇表,元素和特性 定义XML文档的内容。 

    <?xml version="1.0" encoding="gb2312"?>

    元素是XML文档最重要的部分,相较于HTML,XML没有任何预定义的元素和结构。

    在程序中访问并操作.XML文件一般有两种模型,分别是使用

    • 文档对象模型DOM
    • 流模型

    使用DOM的好处在于它允许编辑和更新XML文档,可以随机访问文档中的数据、可以使用XPath查询,但是,DOM的缺点是需要一次性加载整个文档到内存,对于大型文档会造成资源问题。

    流模型对.XML文件的访问采用流的概念,任何时候内存中只有当前节点,但它是只读的、向前的,不能在文档中执行向后导航操作。

    三种常用的读取XML文件的方法:

    • XmlDocument
    • XmlTextReader
    • Linq to Xml

    以如下.XML文档为例进行说明:

    <?xml version="1.0" encoding="gb2312">
    <RootConfig>
      <campaigns>
          <campaign Year="2015">
            <DictDatas Page="p1">
                <Dict name="DeviceNo">
                    <item value="010">北京</item>
                    <item value="021">上海</item>
                     <item value="0536">潍坊</item>
                    <IsComboBox>Yes</IsComboBox>
                </Dict>
            </DictDatas>
         </campaign>
         <campaign  Year="2016">
            <DictDatas Page="p1|p2">
                <Dict name="Student">
                    <FirstName>Sun</FirstName>
                    <LastName>Wjcx.com</LastName>
                </Dict>
                <Dict name="SexNo">
                    <item value="1">女</item>
                    <item value="2">男</item>
                    <IsComboBox>Yes</IsComboBox>
                </Dict>
            </DictDatas>
            <searchFields Page="p1|p2">
                <searchField name="SchoolInfo">
                    <ID>00.00</ID>
                    <SchoolName>Whut.Seu</SchoolName>
                    <Address>Wuhan.NanJing</Address>
                </searchField>
            </searchFields>     
         </campaign>
      </campaigns>
    </RootConfig>  
    

    1、使用XmlDocument   

    XmlDocument基于文档结构模型方式读取.XML,可以把.XML文件看作是由文档声明(Declare)、元素(Element)、属性(Attribute)、文本(Text)等构成的一棵树,通过一系列属性或方法得到结点的值或其它属性:
     例:xn代表一个结点
     xn.Name; // 这个结点的名称
     xn.Value; // 这个结点的值
     xn.ChildNodes; // 这个结点的所有子结点链表
     xn.ParentNode; // 这个结点的父结点

    使用时首先声明一个XmlDocument对象,调用Load方法,从指定路径加载XML文件,推荐格式:

     XmlDocument doc = new XmlDocument();
     XmlReaderSettings settings = new XmlReaderSettings();
     settings.IgnoreComments = true;  // 忽略文档里面的注释
     settings.IgnoreWhiteSpace = true;  // 忽略空白
     XmlReader reader = XmlReader.Create(@"....sqh.xml", settings);
     doc.Load(reader);

    具体属性和方法: 

    XmlNode xnCamps = doc.SelectSingleNode("campaigns"); // 定位结点 
    XmlNodeList campList = doc.SelectNodes("campaign"); // 定位结点链表
    XmlNodeList campList = doc.SelectNodes("campaign[Year<='2016']");

    关于定位结点,有必要学习XML文档的查询语言:xPath,待续… 

    foreach(XmlNode xnCamp in campList)
     {
         XmlElement xeCamp = (XmlElement)xnCamp; // 将节点转换为元素,便于得到节点的属性值
         string nameCamp = xeCamp.Name;
         string yearCamp = xeCamp.GetAttribute("Year").ToString();
         string yearCamp = xeCamp.Attributes["Year"].Value; // 此2行代码等价
    
          XmlElement xeDict =  (XmlElement)xeCamp.SelectSingleNode("DictDatas");
         foreach(XmlNode xnDict in xeDict.ChildNodes)
         {
            XmlElement xeDict = (XmlElement)xnDict;
            string isComboBox = xeDict["ComboBox"].InnerText;
    
            XmlNodeList itemList = xeDic.SelectNodes("item");
            foreach (XmlNode xnItem in itemList)
            {
                XmlElement xeItem = (XmlElement)xnItem;
                string value = xeItem.GetAttribute("value").ToString();
                string innerText = xeItem.InnerText;
            }
         }
     }

    以上代码仅供学习参考,欢迎批评指正。

    2、使用 XmlTextReader

    待续吧…

    3、使用 Linq to Xml

    Linq (Language Itergrated Query,语言集成查询) 是内置于C#中的一种数据查询语言,允许以数据库查询的方式查询数据集合,可以在大型的对象集合、XML、数据库中查询数据。

    不同的Linq变体(Linq to Objects、Linq to Entities、Linq to XML等)可以用于查询、处理不同的数据源(数据库和XML等)。

    Linq

    a. 查询语法 Query Syntax
     声明形式。利用查询表达式。简单易理解,推荐。
     查询表达式:fromselect子句,group子句,where子句,join子句,orderby子句等。
     · join 子句
      用一个查询搜索两个列表中的相关数据,用键字段把结果链接起来。
       from c in Table1
       join o in Table2 on c.ID equals o.ID
     · group 子句
      分组键用 key 区分,返回结果 res 是关于 key 的可枚举类型(分组),每个组也是可枚举类型。  
    b. 方法语法 Method Ayntax
     命令形式。利用标准查询运算符。特殊情况需要传送函数或方法,以委托的形式。注意,方法调用顺序并不固定,因为Linq方法调用返回的类型都实现了 IEnumerable<T> 接口,但是应根据查询特性,合理安排调用顺序。
     System.Linq.Enumerable类声明了标准查询运算符的方法,是扩展了泛型 IEnumerable<T> 的 扩展方法:公共静态方法,参数列表以 this 开始!
     · 直接语法调用:Enumerable.Function(可枚举类型实例);
     · 扩展语法调用:可枚举类型实例.Function();或 可枚举类型实例.Function(Lambda表达式); 
    :返回结果res为 可枚举类型,内存中的表示形式:
     
    其中,res 并不保存查询结果,而是指向 IEnumerable<T>类型的对象。当处理枚举类型时,查询表达式才会执行(延迟执行)。

    聚合运算符:查询大型数据集,分析查询结果。

    Count()、Max()、Min()、Average()、Sum()

    投影 Projection:在查询中创建新的对象。
    a. 投影查询的查询语法
     在select子句中利用 new{} 创建新对象,不能采用 select + 字段列表 的形式。
    b. 投影查询的方法语法
     调用Linq的 Select(Lambda表达式) 方法。
    多级排序
    a. 查询语法
     orderby + 字段列表。
    b. 多级排序的方法语法
     OrderBy().ThenBy()/ThenByDescending()方法。
    组合查询 group
    把数据分解为组,允许按组来排序、计算聚合值以及进行比较。

    分组产生的结果集实现了Linq接口 IEnumerable<IGrouping>,支持 key 属性,所以组合查询中的数据通过一个键(Key)字段来组合,每个组中的所以数据共享这个字段值。
    <-!- 几种常用方法 -!->
    ◊. 分区运算符
     - Take():从查询结果中提取前n个结果;
     - Skip():与Take()相反,跳过前n个结果,返回剩余的结果;
    ◊. 条件查询运算符
     - First():返回结果集中第一个匹配给定条件的元素;
     - FirstOrDefault():查询条件不满足,返回默认元素,而不必添加错误处理代码;
    ◊. 标准的集(合)运算符 set operator
     - Intersect():交集,QryRes1.Intersect(QryRes2);
     - Except():差集,QryRes1.Except(QryRes2);
     - Union():并集,QryRes1.Union(QryRes2);

    Linq to XML

    构建对象
    C#:利用匿名类型 var 和对象初始化器
    Linq to XML:函数构建方式 (Function Construction)。此方式可以创建XML文档,并且可以反映XML文档的嵌套结构
     . XDocument:XML文档声明
     . XElement:元素
     . XAttribute:特性

    XDocument personsDoc = new XDocument(
      new XElement("persons", new XAttribute("Nationality","China"),
        new XElement("person", new XAttribute("ID","101"),  // 属性
          new XElement("Name","sqh"),                      // 元素
          new XElement("Sex","male"),
          new XElement("City", new XAttribute("Province", "ShanDong"), "WeiFang")
        ),
        new XElement("person", new XAttribute("ID", "102"),
          new XElement("Name", "pm"),
          new XElement("Sex", "female"),
          new XElement("City", new XAttribute("Province", "SiChuan"), "NanChong")
        )
      ));
    

    操作方法如下

    personsDoc.Save/Load(); // 保存/加载
    XElement root = personsDoc.Root;  // 根结点 
    IEnumerable<XElement> rootChilds = root.Elements("person");
    foreach (XElement xe in rootChilds){
      xe.Name.ToString(), xe.Attribute("ID").Value // 结点/子结点名字及属性
      xe.Element("City").Value, xe.Element("City").Attribute("Province").Value
    } 
    
    // 增-Add、删-Remove、改-SetElement
    root.SetAttributeValue("民族", "汉");  // 增加/修改属性
    root.Attribute("民族").Remove();       // 删除属性
    root.Add(new XElement("person", new XAttribute("ID","103"),  // 增加结点
           new XElement("Name", "ymn"),
           new XElement("Sex", "female"),
           new XElement("City", new XAttribute("Province", "HuBei"), "XianNing")
       ));
    xe.Remove();   // 删除结点

    利用 Linq 查询表达式进行 XML 树搜索。

    // 查 - Linq to Xml 
    var res = from xe in root.Elements("person")
          where int.Parse(xe.Attribute("ID").Value) <= 102
          select new { Name = xe.Element("Name").Value, City = xe.Element("City").Value};

    参考
    c# 读取XML - 1; - c# 读取XML - 2; 
    关于XmlReader/XmlWriter 类;

    Linq系列 ~ Linq to XML;
    LINQ to XML 建立,读取,增,删,改;

  • 相关阅读:
    Visual C++ 2012/2013的内存溢出检測工具
    MATLAB新手教程
    LCD开发之汉字显示
    支持向量机通俗导论(理解SVM的三层境地)
    类与类之间的简单传值
    hibernate官方新手教程 (转载)
    秒杀多线程第四篇 一个经典的多线程同步问题
    Java的位运算符具体解释实例——与(&amp;)、非(~)、或(|)、异或(^)
    mysql基础:mysql与C结合实例
    php实现字符串的排列(交换)(递归考虑所有情况)
  • 原文地址:https://www.cnblogs.com/wjcx-sqh/p/5929902.html
Copyright © 2020-2023  润新知