You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

414 lines
14 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
/// <summary>
/// XMLParser 简易XML解析方法
///string str = File.ReadAllText(@"config.xml", Encoding.UTF8); //读取XML文件
/////MessageBox.Show(str);
///XMLParser xmlParser = new XMLParser();
///XMLNode xn = xmlParser.Parse(str);
///server = xn.GetValue("items>0>server>0>_text");
/// database = xn.GetValue("items>0>database>0>_text");
/// XMLNode temp = xn.GetNode("items>0>res>0");
///string basePath = temp.GetValue("@basePath");//或直接 basePath=xn.GetValue("items>0>res>0>@basePath");
///当然xml文件内容为
///<? xml version="1.0" encoding="utf-8" ?>
///<items>
/// <server>192.168.52.148</server>
/// <database>world</database>
/// <port>3306</port>
/// <uid>wtx</uid>
/// <password>123456</password>
/// <res basePath = "d:\Resources" language="zh_CN" />
/// /// 得到的解析结果是
//server=192.168.52.148 ; database=world; basePath=d:\Resources
/// </items>
/// </summary>
namespace DSWeb.Areas.CommMng.DAL
{
public class XMLParser
{
private char LT = '<';
private char GT = '>';
private char SPACE = ' ';
private char QUOTE = '"';
private char QUOTE2 = '\'';
private char SLASH = '/';
private char QMARK = '?';
private char EQUALS = '=';
private char EXCLAMATION = '!';
private char DASH = '-';
//private char SQL = '[';
private char SQR = ']';
public XMLNode Parse(string content)
{
XMLNode rootNode = new XMLNode();
rootNode["_text"] = "";
string nodeContents = "";
bool inElement = false;
bool collectNodeName = false;
bool collectAttributeName = false;
bool collectAttributeValue = false;
bool quoted = false;
string attName = "";
string attValue = "";
string nodeName = "";
string textValue = "";
bool inMetaTag = false;
bool inComment = false;
bool inCDATA = false;
XMLNodeList parents = new XMLNodeList();
XMLNode currentNode = rootNode;
for (int i = 0; i < content.Length; i++)
{
char c = content[i];
char cn = '~'; // unused char
char cnn = '~'; // unused char
char cp = '~'; // unused char
if ((i + 1) < content.Length) cn = content[i + 1];
if ((i + 2) < content.Length) cnn = content[i + 2];
if (i > 0) cp = content[i - 1];
if (inMetaTag)
{
if (c == QMARK && cn == GT)
{
inMetaTag = false;
i++;
}
continue;
}
else
{
if (!quoted && c == LT && cn == QMARK)
{
inMetaTag = true;
continue;
}
}
if (inComment)
{
if (cp == DASH && c == DASH && cn == GT)
{
inComment = false;
i++;
}
continue;
}
else
{
if (!quoted && c == LT && cn == EXCLAMATION)
{
if (content.Length > i + 9 && content.Substring(i, 9) == "<![CDATA[")
{
inCDATA = true;
i += 8;
}
else
{
inComment = true;
}
continue;
}
}
if (inCDATA)
{
if (c == SQR && cn == SQR && cnn == GT)
{
inCDATA = false;
i += 2;
continue;
}
textValue += c;
continue;
}
if (inElement)
{
if (collectNodeName)
{
if (c == SPACE)
{
collectNodeName = false;
}
else if (c == GT)
{
collectNodeName = false;
inElement = false;
}
if (!collectNodeName && nodeName.Length > 0)
{
if (nodeName[0] == SLASH)
{
// close tag
if (textValue.Length > 0)
{
currentNode["_text"] += textValue;
}
textValue = "";
nodeName = "";
currentNode = parents.Pop();
}
else
{
if (textValue.Length > 0)
{
currentNode["_text"] += textValue;
}
textValue = "";
XMLNode newNode = new XMLNode();
newNode["_text"] = "";
newNode["_name"] = nodeName;
if (currentNode[nodeName] == null)
{
currentNode[nodeName] = new XMLNodeList();
}
XMLNodeList a = (XMLNodeList)currentNode[nodeName];
a.Push(newNode);
parents.Push(currentNode);
currentNode = newNode;
nodeName = "";
}
}
else
{
nodeName += c;
}
}
else
{
if (!quoted && c == SLASH && cn == GT)
{
inElement = false;
collectAttributeName = false;
collectAttributeValue = false;
if (attName.Length > 0)
{
if (attValue.Length > 0)
{
currentNode["@" + attName] = attValue;
}
else
{
currentNode["@" + attName] = true;
}
}
i++;
currentNode = parents.Pop();
attName = "";
attValue = "";
}
else if (!quoted && c == GT)
{
inElement = false;
collectAttributeName = false;
collectAttributeValue = false;
if (attName.Length > 0)
{
currentNode["@" + attName] = attValue;
}
attName = "";
attValue = "";
}
else
{
if (collectAttributeName)
{
if (c == SPACE || c == EQUALS)
{
collectAttributeName = false;
collectAttributeValue = true;
}
else
{
attName += c;
}
}
else if (collectAttributeValue)
{
if (c == QUOTE || c == QUOTE2)
{
if (quoted)
{
collectAttributeValue = false;
currentNode["@" + attName] = attValue;
attValue = "";
attName = "";
quoted = false;
}
else
{
quoted = true;
}
}
else
{
if (quoted)
{
attValue += c;
}
else
{
if (c == SPACE)
{
collectAttributeValue = false;
currentNode["@" + attName] = attValue;
attValue = "";
attName = "";
}
}
}
}
else if (c == SPACE)
{
}
else
{
collectAttributeName = true;
attName = "" + c;
attValue = "";
quoted = false;
}
}
}
}
else
{
if (c == LT)
{
inElement = true;
collectNodeName = true;
}
else
{
textValue += c;
}
}
}
return rootNode;
}
}
public class XMLNode : Hashtable
{
public XMLNodeList GetNodeList(string path)
{
return GetObject(path) as XMLNodeList;
}
public XMLNode GetNode(string path)
{
return GetObject(path) as XMLNode;
}
public string GetValue(string path)
{
return GetObject(path) as string;
}
private object GetObject(string path)
{
string[] bits = path.Split('>');
XMLNode currentNode = this;
XMLNodeList currentNodeList = null;
bool listMode = false;
object ob;
for (int i = 0; i < bits.Length; i++)
{
if (listMode)
{
currentNode = (XMLNode)currentNodeList[int.Parse(bits[i])];
ob = currentNode;
listMode = false;
}
else
{
ob = currentNode[bits[i]];
if (ob is ArrayList)
{
currentNodeList = (XMLNodeList)(ob as ArrayList);
listMode = true;
}
else
{
// reached a leaf node/attribute
if (i != (bits.Length - 1))
{
// unexpected leaf node
string actualPath = "";
for (int j = 0; j <= i; j++)
{
actualPath = actualPath + ">" + bits[j];
}
//Debug.Log("xml path search truncated. Wanted: " + path + " got: " + actualPath);
}
return ob;
}
}
}
if (listMode)
return currentNodeList;
else
return currentNode;
}
}
public class XMLNodeList : ArrayList
{
public XMLNode Pop()
{
XMLNode item = null;
item = (XMLNode)this[this.Count - 1];
this.Remove(item);
return item;
}
public int Push(XMLNode item)
{
Add(item);
return this.Count;
}
}
}