using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
//XML文件节点访问类,版本1.1
//design by: wxu2
//date:2008-9-3
namespace XMLACCESS
{
public class XmlAdapter
{
XMLNode _RootNode;
XmlTextReader XR;
XmlTextWriter XW;
string _DefaultRoot = "RootNode";
string _DefaultFileName = "Default.xml";
string _FileName;
#region 构造函数
public XmlAdapter()
{
Init();
}
public XmlAdapter(string filename)
{
if (!Open(filename))
{
Open();
}
}
~XmlAdapter()
{
}
#endregion
#region 属性
/// <summary>
/// 把节点结构作为属性抛出,供外部程序修改,Save时,会按修改后的节点结构保存为XML文档
/// </summary>
public XMLNode RootNode
{
get { return _RootNode; }
set { _RootNode = value; }
}
#endregion
#region 方法
public void New()
{
if (!File.Exists(_FileName))
{
Init();
Save();
}
}
public bool New(string filename)
{
string fn = CheckFileName(filename);
if (fn == "") fn = _DefaultFileName;
if (!File.Exists(fn))
{
Init();
return Save(fn);
}
return false;
}
public bool Open()
{
XR = new XmlTextReader(_FileName);
XR.WhitespaceHandling = WhitespaceHandling.None;
while (XR.Read())
{
if (XR.Name.ToUpper() == "XML")
{
_RootNode = ReadNode(null);
XR.Close();
return (_RootNode != null);
}
}
XR.Close();
return true;
}
public bool Open(string filename)
{
string fn = CheckFileName(filename);
if (File.Exists(fn))
{
Init();
_FileName = fn;
return Open();
}
else
New(fn);
return true;
}
public bool Save(string filename)
{
if (filename != null && filename.Trim() != "")
{
_FileName = filename.Trim();
}
return Save();
}
public bool Save()
{
BeginXml();
return EndXml();
}
#region 节点方法
/// <summary>
/// 从指定节点(Node)下的节点树中查找与指定节点名(NodeName)相符的节点,并返回节点列表
/// </summary>
/// <param name="Node"></param>
/// <param name="NodeName"></param>
/// <returns></returns>
public List<XMLNode> FindNode(XMLNode Node, string NodeName)
{
List<XMLNode> lst = new List<XMLNode>();
List<XMLNode> tmp;
if (Node != null)
{
foreach (XMLNode x in Node.ChildNodes)
{
if (x.Name == NodeName)
lst.Add(x);
tmp = FindNode(x, NodeName);
lst=UniteNodeList(lst, tmp);
}
}
return lst;
}
/// <summary>
/// 根据节点路径,在整个节点树中查找与之相符的节点路径,取得最后一个节点,并返回节点列表
/// 节点路径的层次以“/”分隔,如果节点路径字符串中只有一个节点,则按单节点看待。
/// </summary>
/// <param name="NodeNamePath"></param>
/// <returns></returns>
public List<XMLNode> FindNode(string NodeNamePath)
{
List<XMLNode> lst = new List<XMLNode>();
List<XMLNode> tmp = new List<XMLNode>();
int i;
string []ary ;
if (NodeNamePath.IndexOf("/") < 0)
{
ary = new string [1];
ary[0] = NodeNamePath;
}
else
ary = NodeNamePath.Split('/');
/////////////////////////////
if (ary.Length > 0 && _RootNode!=null)
{
for (i = 0; i < ary.Length; i++)
{
if (i == 0 )
{
if (_RootNode.Name == NodeNamePath)
lst.Add(_RootNode);
tmp = FindNode(_RootNode,ary[i]);
lst = UniteNodeList(lst, tmp);
}
else
{
lst = FindChildNodeInList(lst, ary[i]);
}
}
}
return lst;
}
#endregion
#endregion
#region 支持方法
#region 初始化方法
private void Init()
{
_FileName = _DefaultFileName;
_RootNode = new XMLNode();
_RootNode.ChildNodes = new List<XMLNode>();
_RootNode.Attributes = new List<XMLNodeAttribute>();
_RootNode.Name = _DefaultRoot;
_RootNode.Value = "";
}
private string CheckFileName(string filename)
{
if (filename != null && filename.Trim() != "")
return filename.Trim();
return "";
}
private void FixFileName(string filename)
{
string fn = CheckFileName(filename);
if (fn != "")
_FileName = fn;
else
_FileName = _DefaultFileName;
}
#endregion
#region 写XML
private bool BeginXml()
{
try
{
XW = new XmlTextWriter(_FileName, Encoding.UTF8);
XW.Formatting = Formatting.Indented;
XW.WriteStartDocument(false);
WriteNode(_RootNode);
return true;
}
catch
{
XW = null;
return false;
}
}
private bool EndXml()
{
bool isok = (XW != null);
if (isok)
{
XW.WriteEndDocument();
XW.Close();
}
return isok;
}
private void WriteNode(XMLNode Node)
{
int i;
XW.WriteStartElement(Node.Name);
XW.WriteAttributeString("Value", Node.Value);
if (Node.Attributes.Count > 1)
{
for (i = 1; i < Node.Attributes.Count; i++)
{
AddAttribute(Node.Attributes[i]);
}
}
//XW.WriteValue(" ");
if (Node.ChildNodes.Count > 0)
{
foreach (XMLNode n in Node.ChildNodes)
WriteNode(n);
}
EndNode();
}
private void EndNode()
{
XW.WriteFullEndElement();
}
private void AddAttribute(XMLNodeAttribute xat)
{
XW.WriteAttributeString(xat.Name, xat.Value);
}
private void Comment(string comment)
{
}
#endregion
#region 读XML
private XMLNode ReadNode(XMLNode parent)
{
XMLNode n = null;
XMLNode tmp = new XMLNode();
string str;
while (XR.Read())
{
n = new XMLNode();
switch (XR.NodeType)
{
case XmlNodeType.Element:
n.Name = XR.Name;
XR.MoveToNextAttribute();
n.Value = XR.Value;
n.Attributes = ReadNodeAttribute();
if (parent == null)//读根节点入口
{
return ReadNode(n);
}
else
{
ReadNode(n);//读n的子节点
str = n.ReturnNode;
n.ReturnNode = "";
parent.ChildNodes.Add(n);
if (str != "")//有返回标志
{
if (str != n.Name)//不是当前节点,则传递标志
{
parent.ReturnNode = str;
return parent;//返回父节点
}
}
}
break;
case XmlNodeType.EndElement:
parent.ReturnNode = XR.Name;
return parent;
default:
break;
}
}
return parent;
}
private List<XMLNodeAttribute> ReadNodeAttribute()
{
List<XMLNodeAttribute> atts = new List<XMLNodeAttribute>();
XMLNodeAttribute att;
int c;
if (XR.AttributeCount > 1)
{
for (c = 1; c < XR.AttributeCount; c++)
{
XR.MoveToNextAttribute();
att = new XMLNodeAttribute();
att.Name = XR.Name;
att.Value = XR.Value;
atts.Add(att);
}
}
return atts;
}
//查找节点
private List<XMLNode> FindChildNodeInList(List<XMLNode> NodeList, string NodeName)
{
List<XMLNode> lst = new List<XMLNode>();
foreach (XMLNode n in NodeList)
{
lst = UniteNodeList(lst, FindChildNode(n, NodeName));
}
return lst;
}
private List<XMLNode> FindChildNode(XMLNode Node, string NodeName)
{
List<XMLNode> lst = new List<XMLNode>();
foreach (XMLNode n in Node.ChildNodes)
{
if (n.Name == NodeName)
lst.Add(n);
}
return lst;
}
private List<XMLNode> UniteNodeList(List<XMLNode> List1, List<XMLNode> List2)
{
foreach (XMLNode y in List2)
List1.Add(y);
return List1;
}
#endregion
#endregion
}
public class XMLNode
{
List<XMLNode> _ChildNodeList = new List<XMLNode>();
List<XMLNodeAttribute> _AttList = new List<XMLNodeAttribute>();
string _Name;
string _Value;
string _ReturnNode = "";
public string ReturnNode
{
get { return _ReturnNode; }
set { _ReturnNode = value; }
}
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public string Value
{
get { return _Value; }
set { _Value = value; }
}
public List<XMLNodeAttribute> Attributes
{
get { return _AttList; }
set { _AttList = value; }
}
public List<XMLNode> ChildNodes
{
get { return _ChildNodeList; }
set { _ChildNodeList = value; }
}
}
public class XMLNodeAttribute
{
string _Name;
string _Value;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public string Value
{
get { return _Value; }
set { _Value = value; }
}
}
}