<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      LINQ之路20:LINQ to XML之Documents、Declarations和Namespaces

      本篇我們會(huì)討論與XML文檔相關(guān)的另外幾個(gè)重要概念:Documents、Declarations和Namespaces。一個(gè)XDocument封裝了根元素并且允許我們添加XDeclaration, processing instructions, 文檔類型和其他根級類型對象;一個(gè)標(biāo)準(zhǔn)的XML文件總是從一個(gè)declaration(聲明)開始,它的作用是確保文件會(huì)被文件讀取器正確的讀取和理解;就像.NET類型可以有namespaces(命名空間)一樣,XML元素和屬性也可以有namespaces,用于對XML文檔進(jìn)行更有效的管理。

      XDocument

      我們前面已經(jīng)說過,一個(gè)XDocument封裝了根元素并且允許我們添加XDeclaration, processing instructions, 文檔類型和其他根級類型對象。和W3C DOM不同的是,對于LINQ to XML中的X-DOM來講,一個(gè)XDocument對象是可選的,X-DOM并不需要它來把所有對象聯(lián)系起來。

      XDocument提供了和XElement一致的函數(shù)式構(gòu)造器。并且由于XDocument是從Container繼承而來,所以它也支持AddXXX、RemoveXXX、和ReplaceXXX方法。但和XElement不同的是,XDocument可以接受的內(nèi)容是有限制的,它可以接受如下參數(shù):

      • 一個(gè)XElement對象(根元素)
      • 一個(gè)XDeclaration對象
      • 一個(gè)XDocumentType對象
      • 任意數(shù)量的XProcessingInstruction對象
      • 任意數(shù)量的XComment對象

      要?jiǎng)?chuàng)建一個(gè)有效的XDocument,只有根元素是必須的。XDeclaration是可選的,如果它被省略,序列化時(shí)將會(huì)應(yīng)用默認(rèn)的設(shè)置。

      一個(gè)最簡單的XDocument僅有一個(gè)根元素:

                  var doc = new XDocument(
      new XElement("test", "data")
      );

      注意我們并沒有包含XDeclaration對象,但是調(diào)用doc.Save方法生成的文件中還是會(huì)包含XML declaration信息,它會(huì)使用默認(rèn)設(shè)置自動(dòng)生成。

      下面的示例用來生成一個(gè)簡單但完全正確的XHTML文件,它很好的演示了XDocument可以接受的各種構(gòu)造參數(shù):

                  var styleInstruction = new XProcessingInstruction(
      "xml-stylesheet", "href='styles.css' type='text/css'");

      var docType = new XDocumentType("html",
      "-//W3C//DTD XHTML 1.0 Strict//EN",
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", null);

      XNamespace ns = "http://www.w3.org/1999/xhtml";

      var root = new XElement(ns + "html",
      new XElement(ns + "head",
      new XElement(ns + "title", "An XHTML page")),
      new XElement(ns + "body",
      new XElement(ns + "p", "This is the content"))
      );

      var doc = new XDocument(
      new XDeclaration("1.0", "utf-8", "no"),
      new XComment("Reference a stylesheet"),
      styleInstruction,
      docType,
      root);

      doc.Save("D:\\test.html");

      test.html文件的最終結(jié)果如下:

      <?xml version="1.0" encoding="utf-8" standalone="no"?>

      <!--Reference a stylesheet-->
      <?xml-stylesheet href='styles.css' type='text/css'?>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <title>An XHTML page</title>
      </head>
      <body>
      <p>This is the content</p>
      </body>
      </html>

      XDocument的Root屬性可以用來快速的存取其唯一的XElement元素。而XObject的Document屬性則可以快速訪問所在的XDocument對象,X-DOM tree里面的所有對象都繼承了該屬性:

                  Console.WriteLine(doc.Root.Name.LocalName);         // html
      XElement bodyNode = doc.Root.Element(ns + "body");
      Console.WriteLine(bodyNode.Document == doc); // True

      再次強(qiáng)調(diào)一下,document對象的子節(jié)點(diǎn)并沒有Parent對象:

                  Console.WriteLine(doc.Root.Parent == null); // True
      foreach (XNode node in doc.Nodes())
      Console.Write(node.Parent == null); // TrueTrueTrueTrue

       

      XML Declarations

      一個(gè)標(biāo)準(zhǔn)的XML文件總是從一個(gè)declaration(聲明)開始,如下所示:

              <?xml version="1.0" encoding="utf-8" standalone="no"?>

      XML declaration的作用是確保文件會(huì)被文件讀取器正確的讀取和理解。XElement和 XDocument會(huì)遵循以下規(guī)則來處理XML declarations:

      • 提供一個(gè)文件名來調(diào)用Save方法時(shí),總是寫入declaration。
      • 提供XmlWriter來調(diào)用Save方法時(shí),寫入declaration,除非XmlWriter作了專門的指定。
      • ToString方法從不產(chǎn)生XML declaration。

      在構(gòu)造XmlWriter對象時(shí),我們可以通過設(shè)置OmitXmlDeclaration和ConformanceLevel屬性來指示XmlWriter不要產(chǎn)生declaration。

      XDeclaration對象的存在與否并不影響是否寫入XML declaration。換句話說:即使沒有XDeclaration對象,Save方法也會(huì)寫入默認(rèn)的declaration;相反,即使存在XDeclaration對象,ToString()方法也不會(huì)產(chǎn)生declaration。它的目的是告知XML serialization下面的信息:

      • 使用什么字符編碼(text encoding)
      • 如何設(shè)置XML declaration的encoding和standalone屬性

      XDeclaration的構(gòu)造函數(shù)接受3個(gè)參數(shù):version, encoding, 和standalone屬性。下面的例子中,test.xml擁有UTF-16編碼:

                  var doc = new XDocument(
      new XDeclaration("1.0", "utf-16", "yes"),
      new XElement("test", "data")
      );
      doc.Save("test.xml");

      實(shí)際上,XML writer會(huì)忽略第一個(gè)參數(shù)version值,而總是寫入"1.0"。

       

      Names和Namespaces

      就像.NET類型可以有namespaces(命名空間)一樣,XML元素和屬性也可以有namespaces。雖然我們在一般的小項(xiàng)目中可能不會(huì)用到namespaces,但是在產(chǎn)品級的軟件中,我們就必須使用它來對各種XML文檔進(jìn)行管理了。

      XML namespaces有兩個(gè)作用,首先,和C#的namespaces一樣,它可以防止命名沖突。在我們把一個(gè)XML文件中的數(shù)據(jù)合并到另外一個(gè)XML文件時(shí)可能會(huì)出現(xiàn)。其次 ,它賦予一個(gè)Name(名稱)以特別的含義。比如,名稱”nil”可以表示任何東西。但是在http://www.w3.org/2001/xmlschema-instance命名空間中,“nil”表示了C#中的null語義。

      因?yàn)閄ML命名空間非常容易引起混淆,我們將先行介紹該主題的普通含義,然后再討論LINQ to XML對他們的使用方式。

      XML中的Namespaces

      假設(shè)我們希望在CNBlogs.LINQ命名空間中定義一個(gè)customer元素。那么有兩種方法可以選擇。第一種是使用xmlns屬性,如下所示:

              <customer xmlns="CNBlogs.LINQ"/>

      Xmlns是一個(gè)特殊的保留屬性。上例中的xmlns有兩個(gè)作用:

      • 它為當(dāng)前元素指定了一個(gè)命名空間。
      • 它為所有的后代節(jié)點(diǎn)指定了默認(rèn)的命名空間。

      這意味著下面的示例中,address和postcode會(huì)隱式位于CNBlogs.LINQ命名空間之中:

      <customer xmlns="CNBlogs.LINQ">
      <address>
      <postcode>02138</postcode>
      </address>
      </customer>

      如果我們希望address和postcode不使用命名空間,我們需要明確指定,如下所示:

      <customer xmlns="CNBlogs.LINQ">
      <address xmlns="">
      <postcode>02138</postcode><!-- postcode 現(xiàn)在繼承空的命名空間 -->
      </address>
      </customer>
      前綴(Prefix)

      指定命名空間的另一種方式是使用前綴。前綴是我們?yōu)槊臻g指定的一個(gè)別名,目的是為了節(jié)省輸入時(shí)間。

      使用前綴分兩步:定義前綴和使用前綴。我們可以按如下方式同時(shí)完成這兩步操作:

          <nut:customer xmlns:nut="CNBlogs.LINQ"/>

      在上面的代碼中會(huì)發(fā)生兩件特別的事情。后面的xmlns:nut="..."定義了一個(gè)名為nut的前綴,這樣該元素和所有的后代節(jié)點(diǎn)都可以使用該前綴了。前面的nut:customer把新創(chuàng)建的前綴賦給了customer元素。

      和xmlns不同的是,帶前綴的元素并沒有為后代節(jié)點(diǎn)指定默認(rèn)的命名空間,即前綴只作用于當(dāng)前元素。下面的XML中,firstname的命名空間為空:

          <nut:customer xmlns:nut="CNBlogs.LINQ">
      <firstname>Joe</firstname>
      </customer>

      如要為firstname也指定CNBlogs.LINQ命名空間,我們得進(jìn)行如下改寫:

          <nut:customer xmlns:nut="OReilly.Nutshell.CSharp">
      <nut:firstname>Joe</firstname>
      </customer>

      當(dāng)然,我們也可以為了后代節(jié)點(diǎn)定義一個(gè)或多個(gè)前綴,而不必在當(dāng)前節(jié)點(diǎn)中使用它。下面的XML定義了兩個(gè)前綴:i和z,但當(dāng)前的customer元素命名空間保持為空:

          <customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:z
      ="http://schemas.microsoft.com/2003/10/Serialization/">
      ...
      </customer>

      如果customer是根節(jié)點(diǎn),那么整個(gè)document都將擁有i和z命名空間。

      當(dāng)我們需要從多個(gè)命名空間中獲取元素時(shí),使用前綴就會(huì)非常方便,我們可以為每個(gè)命名空間定義一個(gè)前綴。

      在X-DOM中指定Namespaces

      到目前為止,我們只為XElement和XAttribute使用了簡單的名字(一個(gè)簡單的字符串)。它表示該XML name位于空的命名空間中,就像.NET全局命名空間中的類型一樣。

      有數(shù)種方式可以在X-DOM中指定命名空間。第一種是在名稱之前的大括號中指定,如下所示:

                  var e = new XElement ("{http://www.rzrgm.cn/xmlspace}customer", "LifePoem");
      Console.WriteLine (e.ToString());

      //產(chǎn)生的XML如下:
      <customer xmlns="http://www.rzrgm.cn/xmlspace">LifePoem</customer>

      第二張(更有效率)的方式是使用XNamespace和XName類型。下面是他們的定義:

          public sealed class XNamespace
      {
      public string NamespaceName { get; }
      }
      public sealed class XName // 一個(gè)本地名稱和一個(gè)可選的namespace
      {
      public string LocalName { get; }
      public XNamespace Namespace { get; } // 可選
      }

      這兩個(gè)類型都定義了來自string的隱式轉(zhuǎn)換,所以下面的代碼是正確的:

                  XNamespace ns = "http://www.rzrgm.cn/xmlspace";
      XName localName = "customer";
      XName fullName = "{http://www.rzrgm.cn/xmlspace}customer";

      XName還重載了+運(yùn)算符,這允許我們不使用大括號來組合namespace和name:

                  XNamespace ns = "http://www.rzrgm.cn/xmlspace";
      XName fullName = ns + "customer";
      Console.WriteLine(fullName); // {http://www.rzrgm.cn/xmlspace}customer

      實(shí)際上,X-DOM中所有接受元素或?qū)傩悦Q的的構(gòu)造函數(shù)和方法,其參數(shù)類型為XName而不是string。在我們前面的例子中可以使用string的原因是隱式轉(zhuǎn)換。

      不管是元素還是屬性,指定命名空間的方式都是一樣的:

                  XNamespace ns = "http://domain.com/xmlspace";
      var data = new XElement(ns + "data",
      new XAttribute(ns + "id", 123)
      );

      X-DOM和默認(rèn)命名空間

      在X-DOM的創(chuàng)建過程中它會(huì)忽略默認(rèn)命名空間的概念,直到真正輸出XML時(shí)才會(huì)使用默認(rèn)命名空間。這意味著,我們在創(chuàng)建子元素時(shí),我們必須顯示指定必須的命名空間,它不會(huì)從父節(jié)點(diǎn)繼承:

                  XNamespace ns = "http://www.rzrgm.cn/xmlspace";
      var data = new XElement(ns + "data",
      new XElement(ns + "customer", "Bloggs"),
      new XElement(ns + "purchase", "Bicycle")
      );
      Console.WriteLine(data.ToString());

      但是,當(dāng)X-DOM讀取或輸出XML時(shí),它會(huì)應(yīng)用默認(rèn)的命名空間,所以上面的代碼輸出如下:

          <data xmlns="http://www.rzrgm.cn/xmlspace">
      <customer>Bloggs</customer>
      <purchase>Bicycle</purchase>
      </data>

      下面的代碼:

                  Console.WriteLine (data.Element (ns + "customer").ToString());
      // 輸出單個(gè)元素時(shí)會(huì)加上默認(rèn)的命名空間:
      <customer xmlns="http://www.rzrgm.cn/xmlspace">Bloggs</customer>

      如果我們在創(chuàng)建子XElement時(shí)沒有指定命名空間,那么他們的命名空間為空,如下所示:

                  XNamespace ns = "http://www.rzrgm.cn/xmlspace";
      var data = new XElement(ns + "data",
      new XElement("customer", "Bloggs"),
      new XElement("purchase", "Bicycle")
      );
      Console.WriteLine(data.ToString());

      我們會(huì)得到如下結(jié)果:

          <data xmlns="http://www.rzrgm.cn/xmlspace">
      <customer xmlns="">Bloggs</customer>
      <purchase xmlns="">Bicycle</purchase>
      </data>

      另外一個(gè)可能的陷阱是我們在導(dǎo)航X-DOM時(shí)沒有加上適當(dāng)?shù)拿臻g:

                  XNamespace ns = "http://www.rzrgm.cn/xmlspace";
      var data = new XElement(ns + "data",
      new XElement(ns + "customer", "Bloggs"),
      new XElement(ns + "purchase", "Bicycle")
      );
      XElement x = data.Element(ns + "customer"); // 正確
      XElement y = data.Element("customer"); // 錯(cuò)誤,返回null

      如果我們在創(chuàng)建X-DOM tree時(shí)沒有指定命名空間,我們可以通過如下代碼為所有元素指定一個(gè)命名空間:

                  foreach (XElement e in data.DescendantsAndSelf())
      if (e.Name.Namespace == "")
      e.Name = ns + e.Name.LocalName;

      前綴/Prefixes

      X-DOM只是把前綴作為序列化功能來使用,這意味著我們可以選擇完全忽略前綴問題。唯一的例外是當(dāng)我們在輸出一個(gè)XML文件時(shí)為了取得更好的效率。比如,考慮下面的代碼:

                  XNamespace ns1 = "http://www.rzrgm.cn/space1";
      XNamespace ns2 = "http://www.rzrgm.cn/space2";
      var mix = new XElement(ns1 + "data",
      new XElement(ns2 + "element", "value"),
      new XElement(ns2 + "element", "value"),
      new XElement(ns2 + "element", "value")
      );

      默認(rèn)情況下,XElement會(huì)被序列化為如下格式:

      <data xmlns="http://www.rzrgm.cn/space1">
      <element xmlns="http://www.rzrgm.cn/space2">value</element>
      <element xmlns="http://www.rzrgm.cn/space2">value</element>
      <element xmlns="http://www.rzrgm.cn/space2">value</element>
      </data>

      正如你所看到的,這里有一些沒有必要的重復(fù)。解決方案不是改變創(chuàng)建X-DOM的方式,而是給序列化器一個(gè)暗示,用前綴來簡化相關(guān)的命名空間。這可以通過添加定義前綴的屬性來完成,并且通常由根元素來完成:

                  mix.SetAttributeValue(XNamespace.Xmlns + "ns1", ns1);
      mix.SetAttributeValue(XNamespace.Xmlns + "ns2", ns2);

      這會(huì)把前綴 “ns1”賦給XNamespace變量ns1,“ns2”賦給ns2。這樣X-DOM在序列化時(shí)會(huì)自動(dòng)使用這些屬性來簡化最終的XML。下面是在mix上調(diào)用ToString方法的最終結(jié)果:

      <ns1:data xmlns:ns1="http://domain.com/space1"
      xmlns:ns2
      ="http://domain.com/space2">
      <ns2:element>value</ns2:element>
      <ns2:element>value</ns2:element>
      <ns2:element>value</ns2:element>
      </ns1:data>

      使用前綴并不改變我們創(chuàng)建、查詢或更新X-DOM的方式,所以我們就好像前綴不存在一樣繼續(xù)在程序中使用全名。只有在從XML文件/流中讀取或?qū)懭霑r(shí)才會(huì)使用前綴。

      下一篇也是LINQ to XML的最后一篇,我們將會(huì)和大家討論使用LINQ to XML來生成X-DOM的方式。

      posted @ 2011-12-12 17:20  Life a Poem  閱讀(6464)  評論(4)    收藏  舉報(bào)
      主站蜘蛛池模板: 欧美国产日韩久久mv| 欧美日激情日韩精品嗯| 国产无人区码一区二区| 精品熟女少妇av免费久久| 国产欧美一区二区日本加勒比| 精品亚洲精品日韩精品| 国产在线拍揄自揄拍无码| 久久久久久综合网天天| 国产精品人成视频免费国产| 午夜精品区| 国内自拍偷拍一区二区三区| 18禁在线一区二区三区| 精品人妻中文字幕av| 国产精品一国产精品亚洲| 天堂v亚洲国产v第一次| 中文字幕日韩国产精品| 国产福利视频区一区二区| 国产亚欧女人天堂AV在线| 日韩丝袜人妻中文字幕| 国产免费午夜福利在线播放| 老熟妇高潮一区二区三区| 国产精品成人中文字幕| 亚洲第一香蕉视频啪啪爽| 97国产露脸精品国产麻豆| 亚洲欧美日韩成人综合一区| 国内精品免费久久久久电影院97| 久久96热在精品国产高清| 国产欧美日韩免费看AⅤ视频| 亚洲性图日本一区二区三区| 无码帝国www无码专区色综合| 亚洲第一狼人天堂网伊人| 一区二区三区激情都市| 大埔县| 精品久久人人妻人人做精品| 欧美黑人XXXX性高清版| 国产精品中文字幕综合| 久久精品女人天堂av免费观看| 亚洲精品美女久久久久9999 | 日韩中文字幕国产精品| 国产国产人免费人成免费| 欧美精品在线观看|