熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

在VisualC#中使用XML指南之讀取XML

2013-11-13 09:58:37  來源: .NET編程 
對於XML想必各位都比較了解我也就不用費筆墨來描述它是什麼了我想在未來的Web開發中XML一定會大放異彩XML是可擴展標記語言使用它企業可以制定一套自己的數據格式數據按照這種格式在網絡中傳輸然後再通過XSLT將數據轉換成用戶期望的樣子表示出來這樣便輕易的解決了數據格式不兼容的問題用於Internet的數據傳輸我想這是XML對於我們這些程序員最誘人的地方!
   我們今天的主題不是論述XML的好處而是討論在C#中如何使用XML下面我們來了解一下使用程序訪問XML的一些基礎理論知識

  訪問的兩種模型

  在程序中訪問進而操作XML文件一般有兩種模型分別是使用DOM(文檔對象模型)和流模型使用DOM的好處在於它允許編輯和更新XML文檔可以隨機訪問文檔中的數據可以使用XPath查詢但是DOM的缺點在於它需要一次性的加載整個文檔到內存中對於大型的文檔這會造成資源問題流模型很好的解決了這個問題因為它對XML文件的訪問采用的是流的概念也就是說任何時候在內存中只有當前節點但它也有它的不足它是只讀的僅向前的不能在文檔中執行向後導航操作雖然是各有千秋但我們也可以在程序中兩者並用實現優劣互補嘛呵呵這是題外話了!我們今天主要討論XML的讀取那我們就詳細討論一下流模型吧!

  流模型中的變體

  流模型每次迭代XML文檔中的一個節點適合於處理較大的文檔所耗內存空間小流模型中有兩種變體——模型和模型

  推模型也就是常說的SAXSAX是一種靠事件驅動的模型也就是說它每發現一個節點就用推模型引發一個事件而我們必須編寫這些事件的處理程序這樣的做法非常的不靈活也很麻煩

  NET中使用的是基於模型的實現方案模型在遍歷文檔時會把感興趣的文檔部分從讀取器中拉出不需要引發事件允許我們以編程的方式訪問文檔這大大的提高了靈活性在性能上模型可以選擇性的處理節點而SAX每發現一個節點都會通知客戶機從而使用模型可以提高Application的整體效率NET中模型是作為XmlReader類實現的下面看一下該類的繼承結構



  我們今天來講一下該體系結構中的XmlTextReader類該類提供對Xml文件進行讀取的功能它可以驗證文檔是否格式良好如果不是格式良好的Xml文檔該類在讀取過程中將會拋出XmlException異常可使用該類提供的一些方法對文檔節點進行讀取篩選等操作以及得到節點的名稱和值請牢記XmlTextReader是基於流模型的實現打個不恰當的比喻XML文件就好象水源閘一開水就流出流過了就流過了不會也不可以往回流內存中任何時候只有當前節點你可以使用XmlTextReader類的Read()方法讀取下一個節點好了說了這麼多來看一個例子編程要注重實際對吧看代碼前先看下運行效果吧!



  Example按紐遍歷文檔讀取數據ExampleExample按紐得到節點類型Example過濾文檔只獲得數據內容Example得到屬性節點Example按紐得到命名空間Example顯示整個XML文檔為此我專門寫一個類來封裝以上功能該類代碼如下


//
//XmlReader類用於Xml文件的一般讀取操作以下對這個類做簡單介紹
//
//Attributes(屬性):
//listBox: 設置該屬性主要為了得到客戶端控件以便於顯示所讀到的文件的內容(這裡是ListBox控件)
//xmlPath: 設置該屬性為了得到一個確定的Xml文件的絕對路徑
//
//Basilic Using(重要的引用):
//SystemXml: 該命名空間中封裝有對Xml進行操作的常用類本類中使用了其中的XmlTextReader類
//XmlTextReader: 該類提供對Xml文件進行讀取的功能它可以驗證文檔是否格式良好如果不是格式 // 良好的Xml文檔該類在讀取過程中將會拋出XmlException異常可使用該類提供的
// 一些方法對文檔節點進行讀取篩選等操作以及得到節點的名稱和值
//
//bool XmlTextReaderRead(): 讀取流中下一個節點當讀完最後一個節點再次調用該方法該方法返回false
//XmlNodeType XmlTextReaderNodeType: 該屬性返回當前節點的類型
// XmlNodeTypeElement 元素節點
// XmlNodeTypeEndElement 結尾元素節點
// XmlNodeTypeXmlDeclaration 文檔的第一個節點
// XmlNodeTypeText 文本節點
//bool XmlTextReaderHasAttributes: 當前節點有沒有屬性返回true或false
//string XmlTextReaderName: 返回當前節點的名稱
//string XmlTextReaderValue: 返回當前節點的值
//string XmlTextReaderLocalName: 返回當前節點的本地名稱
//string XmlTextReaderNamespaceURI: 返回當前節點的命名空間URI
//string XmlTextReaderPrefix: 返回當前節點的前綴
//bool XmlTextReaderMoveToNextAttribute(): 移動到當前節點的下一個屬性
//

namespace XMLReading
{
 using System;
 using SystemXml;
 using SystemWindowsForms;
 using SystemComponentModel;

 /// <summary>
 /// Xml文件讀取器
 /// </summary>

 public class XmlReader : IDisposable
 {
  private string _xmlPath;
  private const string _errMsg = Error Occurred While Reading ;
  private ListBox _listBox;
  private XmlTextReader xmlTxtRd;

  #region XmlReader 的構造器

  public XmlReader()
  {
   this_xmlPath = stringEmpty;
   this_listBox = null;
   thisxmlTxtRd = null;
  }

  /// <summary>
  /// 構造器
  /// </summary>
  /// <param name=_xmlPath>xml文件絕對路徑</param>
  /// <param name=_listBox>列表框用於顯示xml</param>

  public XmlReader(string _xmlPath ListBox _listBox)
  {
   this_xmlPath = _xmlPath;
   this_listBox = _listBox;
   thisxmlTxtRd = null;
  }

  #endregion
  #region XmlReader 的資源釋放方法

  /// <summary>
  /// 清理該對象所有正在使用的資源

  /// </summary>

  public void Dispose()
  {
   thisDispose(true);
   GCSuppressFinalize(this);
  }

  /// <summary>
  /// 釋放該對象的實例變量
  /// </summary>
  /// <param name=disposing></param>

  protected virtual void Dispose(bool disposing)
  {
   if (!disposing)
    return;
   if (thisxmlTxtRd != null)
   {
    thisxmlTxtRdClose();
    thisxmlTxtRd = null;
   }

   if (this_xmlPath != null)
   {
    this_xmlPath = null;
   }
  }

  #endregion 
  #region XmlReader 的屬性

  /// <summary>
  /// 獲取或設置列表框用於顯示xml
  /// </summary>

  public ListBox listBox
  {
   get
   {
    return this_listBox;
   }
   set
   {
    this_listBox = value;
   }
  }

  /// <summary>
  /// 獲取或設置xml文件的絕對路徑
  /// </summary>

  public string xmlPath
  {
   get
   {
    return this_xmlPath;
   }
   set
   {
    this_xmlPath = value;
   }
  }

  #endregion

  /// <summary>
  /// 遍歷Xml文件
  /// </summary>

  public void EachXml()
  {
   this_listBoxItemsClear();
   thisxmlTxtRd = new XmlTextReader(this_xmlPath);

   try
   {
    while(xmlTxtRdRead())
    {
     this_listBoxItemsAdd(thisxmlTxtRdValue);
    }
   }
   catch(XmlException exp)
   {
    throw new XmlException(_errMsg + this_xmlPath + expToString());
   }
   finally
   {
    if (thisxmlTxtRd != null)
     thisxmlTxtRdClose();
   }
  }

  /// <summary>
  /// 讀取Xml文件的節點類型
  /// </summary>

  public void ReadXmlByNodeType()
  {
   this_listBoxItemsClear();
   thisxmlTxtRd = new XmlTextReader(this_xmlPath);

   try
   {
    while(xmlTxtRdRead())
    {
     this_listBoxItemsAdd(thisxmlTxtRdNodeTypeToString());
    }
   }
   catch(XmlException exp)
   {
    throw new XmlException(_errMsg + this_xmlPath + expToString());
   }
   finally
   {
    if (thisxmlTxtRd != null)
     thisxmlTxtRdClose();
   }
  }

  /// <summary>
  /// 根據節點類型過濾Xml文檔
  /// </summary>
  /// <param name=xmlNType>XmlNodeType 節點類型的數組</param>

  public void FilterByNodeType(XmlNodeType[] xmlNType)
  {
   this_listBoxItemsClear();
   thisxmlTxtRd = new XmlTextReader(this_xmlPath);
   try
   {
    while(xmlTxtRdRead())
    {
     for (int i = ; i < xmlNTypeLength; i++)
     {
      if (xmlTxtRdNodeType == xmlNType[i])
      {
       this_listBoxItemsAdd(xmlTxtRdName + is Type + xmlTxtRdNodeTypeToString());
      }
     }
    }
   }
   catch(XmlException exp)
   {
    throw new XmlException(_errMsg + thisxmlPath + expToString());
   }
   finally
   {
    if (thisxmlTxtRd != null)
     thisxmlTxtRdClose();
   }
  }

  /// <summary>
  /// 讀取Xml文件的所有文本節點值

  /// </summary>

  public void ReadXmlTextValue()
  {
   this_listBoxItemsClear();
   thisxmlTxtRd = new XmlTextReader(this_xmlPath);

   try
   {
    while(xmlTxtRdRead())
    {
     if (xmlTxtRdNodeType == XmlNodeTypeText)
     {
      this_listBoxItemsAdd(xmlTxtRdValue);
     }
    }
   }
   catch(XmlException xmlExp)
   {
    throw new XmlException(_errMsg + this_xmlPath + xmlExpToString());
   }
   finally
   {
    if (thisxmlTxtRd != null)
     thisxmlTxtRdClose();
   }
  }

  /// <summary>
  /// 讀取Xml文件的屬性
  /// </summary>

  public void ReadXmlAttributes()
  {
   this_listBoxItemsClear();
   thisxmlTxtRd = new XmlTextReader(this_xmlPath);

   try
   {
    while(xmlTxtRdRead())
    {
     if (xmlTxtRdNodeType == XmlNodeTypeElement)
     {
      if (xmlTxtRdHasAttributes)
      {
       this_listBoxItemsAdd(The Element + xmlTxtRdName + has + xmlTxtRdAttributeCount + Attributes);

       this_listBoxItemsAdd(The Attributes are:);

       while(xmlTxtRdMoveToNextAttribute())
       {
        this_listBoxItemsAdd(xmlTxtRdName + = + xmlTxtRdValue);
       }
      }
      else
      {
       this_listBoxItemsAdd(The Element + xmlTxtRdName + has no Attribute);
      }
      this_listBoxItemsAdd();
     }
    }
   }
   catch(XmlException xmlExp)
   {
    throw new XmlException(_errMsg + this_xmlPath + xmlExpToString());
   }
   finally
   {
    if (thisxmlTxtRd != null)
     thisxmlTxtRdClose();
   }
  }

  /// <summary>
  /// 讀取Xml文件的命名空間
  /// </summary>

  public void ReadXmlNamespace()
  {
   this_listBoxItemsClear();
   thisxmlTxtRd = new XmlTextReader(this_xmlPath);
   try
   {
    while(xmlTxtRdRead())
    {
     if (xmlTxtRdNodeType == XmlNodeTypeElement && xmlTxtRdPrefix != )
     {
      this_listBoxItemsAdd(The Prefix + xmlTxtRdPrefix + is associated with namespace + xmlTxtRdNamespaceURI);

      this_listBoxItemsAdd(The Element with the local name + xmlTxtRdLocalName + is associated with + the namespace + xmlTxtRdNamespaceURI);
     }

     if (xmlTxtRdNodeType == XmlNodeTypeElement && xmlTxtRdHasAttributes)
     {
      while(xmlTxtRdMoveToNextAttribute())
      {
       if (xmlTxtRdPrefix != )
       {
        this_listBoxItemsAdd(The Prefix + xmlTxtRdPrefix + is associated with namespace + xmlTxtRdNamespaceURI);

        this_listBoxItemsAdd(The Attribute with the local name + xmlTxtRdLocalName + is associated with the namespace + xmlTxtRdNamespaceURI);

       }
      }
     }
    }
   }
   catch(XmlException xmlExp)
   {
    throw new XmlException(_errMsg + this_xmlPath + xmlExpToString());
   }
   finally
   {
    if (thisxmlTxtRd != null)
     thisxmlTxtRdClose();
   }
  }

  /// <summary>
  /// 讀取整個Xml文件
  /// </summary>

  public void ReadXml()
  {
   string attAndEle = stringEmpty;
   this_listBoxItemsClear();
   thisxmlTxtRd = new XmlTextReader(this_xmlPath);

   try
   {
    while(xmlTxtRdRead())
    {
     if (xmlTxtRdNodeType == XmlNodeTypeXmlDeclaration)
      this_listBoxItemsAdd(stringFormat(<?{} {} ?>xmlTxtRdNamexmlTxtRdValue));
     else if (xmlTxtRdNodeType == XmlNodeTypeElement)
     {
      attAndEle = stringFormat(<{} xmlTxtRdName);
      if (xmlTxtRdHasAttributes)
      {
       while(xmlTxtRdMoveToNextAttribute())
       {
        attAndEle = attAndEle + stringFormat({}={} xmlTxtRdNamexmlTxtRdValue);
       }
      }

      attAndEle = attAndEleTrim() + ;
      this_listBoxItemsAdd(attAndEle);
     }
     else if (xmlTxtRdNodeType == XmlNodeTypeEndElement)
      this_listBoxItemsAdd(stringFormat(</{}>xmlTxtRdName));
     else if (xmlTxtRdNodeType == XmlNodeTypeText)
      this_listBoxItemsAdd(xmlTxtRdValue);
    }
   }
   catch(XmlException xmlExp)
   {
    throw new XmlException(_errMsg + this_xmlPath + xmlExpToString());
   }
   finally
   {
    if (thisxmlTxtRd != null)
     thisxmlTxtRdClose();
   }
  }
 }
}


  窗體代碼如下

namespace XMLReading

{

using System;

using SystemDrawing;

using SystemCollections;

using SystemComponentModel;

using SystemWindowsForms;

using SystemData;

using SystemXml;



public class Form : SystemWindowsFormsForm

{

private SystemWindowsFormsListBox listBox;

private SystemWindowsFormsButton button;

private SystemWindowsFormsButton button;

private SystemWindowsFormsButton button;

private SystemWindowsFormsButton button;

private SystemWindowsFormsButton button;

private SystemWindowsFormsButton button;

private SystemWindowsFormsButton button;

private string xmlPath;

private XmlReader xRead;

/// <summary>

/// 必需的設計器變量

/// </summary>

private SystemComponentModelContainer components = null;



public Form()

{

InitializeComponent();

}



/// <summary>

/// 清理所有正在使用的資源

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

componentsDispose();

}

}

baseDispose( disposing );

}



#region Windows 窗體設計器生成的代碼

/// <summary>

/// 設計器支持所需的方法 不要使用代碼編輯器修改

/// 此方法的內容

/// </summary>

private void InitializeComponent()

{

thislistBox = new SystemWindowsFormsListBox();

thisbutton = new SystemWindowsFormsButton();

thisbutton = new SystemWindowsFormsButton();

thisbutton = new SystemWindowsFormsButton();

thisbutton = new SystemWindowsFormsButton();

thisbutton = new SystemWindowsFormsButton();

thisbutton = new SystemWindowsFormsButton();

thisbutton = new SystemWindowsFormsButton();

thisSuspendLayout();

//

// listBox

//

thislistBoxAnchor = ((SystemWindowsFormsAnchorStyles)((((SystemWindowsFormsAnchorStylesTop | SystemWindowsFormsAnchorStylesBottom)

| SystemWindowsFormsAnchorStylesLeft)

| SystemWindowsFormsAnchorStylesRight)));

thislistBoxItemHeight = ;

thislistBoxLocation = new SystemDrawingPoint( );

thislistBoxName = listBox;

thislistBoxSize = new SystemDrawingSize( );

thislistBoxTabIndex = ;

//

// button

//

thisbuttonAnchor = ((SystemWindowsFormsAnchorStyles)((SystemWindowsFormsAnchorStylesBottom | SystemWindowsFormsAnchorStylesLeft)));

thisbuttonLocation = new SystemDrawingPoint( );

thisbuttonName = button;

thisbuttonTabIndex = ;

thisbuttonText = Example;

thisbuttonClick += new SystemEventHandler(thisbutton_Click);

//

// button

//

thisbuttonAnchor = ((SystemWindowsFormsAnchorStyles)((SystemWindowsFormsAnchorStylesBottom | SystemWindowsFormsAnchorStylesLeft)));

thisbuttonLocation = new SystemDrawingPoint( );

thisbuttonName = button;

thisbuttonTabIndex = ;

thisbuttonText = Example;

thisbuttonClick += new SystemEventHandler(thisbutton_Click);

//

// button

//

thisbuttonAnchor = ((SystemWindowsFormsAnchorStyles)((SystemWindowsFormsAnchorStylesBottom | SystemWindowsFormsAnchorStylesRight)));

thisbuttonLocation = new SystemDrawingPoint( );

thisbuttonName = button;

thisbuttonTabIndex = ;

thisbuttonText = Example;

thisbuttonClick += new SystemEventHandler(thisbutton_Click);

//

// button

//

thisbuttonAnchor = ((SystemWindowsFormsAnchorStyles)((SystemWindowsFormsAnchorStylesBottom | SystemWindowsFormsAnchorStylesLeft)));

thisbuttonLocation = new SystemDrawingPoint( );

thisbuttonName = button;

thisbuttonTabIndex = ;

thisbuttonText = Example;

thisbuttonClick += new SystemEventHandler(thisbutton_Click);

//

// button

//

thisbuttonAnchor = ((SystemWindowsFormsAnchorStyles)((SystemWindowsFormsAnchorStylesBottom | SystemWindowsFormsAnchorStylesLeft)));

thisbuttonLocation = new SystemDrawingPoint( );

thisbuttonName = button;

thisbuttonTabIndex = ;

thisbuttonText = Example;

thisbuttonClick += new SystemEventHandler(thisbutton_Click);

//

// button

//

thisbuttonAnchor = ((SystemWindowsFormsAnchorStyles)((SystemWindowsFormsAnchorStylesBottom | SystemWindowsFormsAnchorStylesLeft)));

thisbuttonLocation = new SystemDrawingPoint( );

thisbuttonName = button;

thisbuttonTabIndex = ;

thisbuttonText = Example;

thisbuttonClick += new SystemEventHandler(thisbutton_Click);

//

// button

//

thisbuttonAnchor = ((SystemWindowsFormsAnchorStyles)((SystemWindowsFormsAnchorStylesBottom | SystemWindowsFormsAnchorStylesLeft)));

thisbuttonLocation = new SystemDrawingPoint( );

thisbuttonName = button;

thisbuttonTabIndex = ;

thisbuttonText = Example;

thisbuttonClick += new SystemEventHandler(thisbutton_Click);

//

// Form

//

thisAutoScaleBaseSize = new SystemDrawingSize( );

thisClientSize = new SystemDrawingSize( );

thisControlsAdd(thisbutton);

thisControlsAdd(thisbutton);

thisControlsAdd(thisbutton);

thisControlsAdd(thisbutton);

thisControlsAdd(thisbutton);

thisControlsAdd(thisbutton);

thisControlsAdd(thisbutton);

thisControlsAdd(thislistBox);

thisName = Form;

thisText = XMLReader;

thisResumeLayout(false);

//

// xmlPath

//

thisxmlPath = samplexml;

}

#endregion



/// <summary>

/// 應用程序的主入口點

/// </summary>

[STAThread]

static void Main()

{

ApplicationRun(new Form());

}



private void button_Click(object sender SystemEventArgs e)

{

xRead = new XmlReader(thisxmlPaththislistBox);



try

{

xReadEachXml();

}

catch(XmlException xmlExp)

{

MessageBoxShow(xmlExpToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

catch(Exception exp)

{

MessageBoxShow(expToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

finally

{

xReadDispose();

}

}



private void button_Click(object sender SystemEventArgs e)

{

xRead = new XmlReader(thisxmlPaththislistBox);



try

{

xReadReadXmlByNodeType();

}

catch(XmlException xmlExp)

{

MessageBoxShow(xmlExpToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

catch(Exception exp)

{

MessageBoxShow(expToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

finally

{

xReadDispose();

}

}



private void button_Click(object sender SystemEventArgs e)

{

XmlNodeType[] xmlNType = {XmlNodeTypeElement XmlNodeTypeEndElement XmlNodeTypeXmlDeclaration};

xRead = new XmlReader(thisxmlPath thislistBox);



try

{

xReadFilterByNodeType(xmlNType);

}

catch(XmlException xmlExp)

{

MessageBoxShow(xmlExpToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

catch(Exception exp)

{

MessageBoxShow(expToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

finally

{

xReadDispose();

}

}



private void button_Click(object sender SystemEventArgs e)

{

xRead = new XmlReader(thisxmlPath thislistBox);



try

{

xReadReadXmlTextValue();

}

catch(XmlException xmlExp)

{

MessageBoxShow(xmlExpToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

catch(Exception exp)

{

MessageBoxShow(expToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

finally

{

xReadDispose();

}

}



private void button_Click(object sender SystemEventArgs e)

{

xRead = new XmlReader(thisxmlPath thislistBox);



try

{

xReadReadXmlAttributes();

}

catch(XmlException xmlExp)

{

MessageBoxShow(xmlExpToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

catch(Exception exp)

{

MessageBoxShow(expToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

finally

{

xReadDispose();

}

}



private void button_Click(object sender SystemEventArgs e)

{

xRead = new XmlReader(thisxmlPath thislistBox);



try

{

xReadReadXmlNamespace();

}

catch(XmlException xmlExp)

{

MessageBoxShow(xmlExpToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

catch(Exception exp)

{

MessageBoxShow(expToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

finally

{

xReadDispose();

}

}



private void button_Click(object sender SystemEventArgs e)

{

xRead = new XmlReader(thisxmlPath thislistBox);



try

{

xReadReadXml();

}

catch(XmlException xmlExp)

{

MessageBoxShow(xmlExpToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

catch(Exception exp)

{

MessageBoxShow(expToString()ErrorMessageBoxButtonsOKMessageBoxIconError);

}

finally

{

xReadDispose();

}

}

}

}


  以下是用於測試的XML文件

  在項目中新建一個XML文件取名為samplexml建好後把該文件拷到項目的bin目錄下的Debug目錄下

<?xml version= encoding=utf ?>

<Invoices date=// xmlns:cat=uri:BusinessCategories

<customers custname=Chile Wines Inc phone= email= custid= delivery=international offerID=

<cat:businfo>Wine Division South</cat:businfo>

<cat:businfo>Beer Division North</cat:businfo>

<order orderID=OID batchid=

<details>

<items cat:num=

<item>Rancagua While</item>

<item>Rancagua Red</item>

</items>

</details>

</order>

<order orderID=OID

<details>

<items num=

<item>Chillan Red</item>

<item>Rancagua While</item>

<item>Santiago Red</item>

<item>Rancagua While</item>

<item>Rancagua Red</item>

</items>

</details>

</order>

<order orderID=OID batchid=

<details>

<items num=

<item>Rancegao Red</item>

<item>Sutothad Black</item>

<item>BlackNme Blue</item>

<item>Booklist Red</item>

<item>Rancegao White</item>

</items>

</details>

</order>

</customers>

</Invoices>
From:http://tw.wingwit.com/Article/program/net/201311/12170.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.