- 首页 > it技术 > >
C# 轻量级解析XML——XMLParser用XMLParser解析XML文件,是因为工作Unity发布WinPhone版本是不支持System.xml这个类库
XMLparser这个类库(其实就三个.cs文件)。这里介绍下XMLParser的原理,XMLParser应就三个类文件 XMLParser,XMLNode,XMLNodeList,顾名思义,XMLParser就是解析XML的实现类(基于字符匹配解析的,具体细节可以看代码,我是没心思看这个了,太绕了),XMLNode就是将解析出来的“项”存储为XMLNode,其实就是一个Hashtable,XMLNodeList就不用多说了。查询的时候就是需要查询项的“路径”字符串传入XMLNode(Hashtable)查找返回。所以直接附上这几行教程:C#代码
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");
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代码
192.168.52.148
world3306
wtx123456
192.168.52.148
world【Unity|Unity中XMLParser的使用】3306
wtx123456
得到的解析结果是 Xml代码
server=192.168.52.148 ;
database=world;
basePath=d:\Resources
server=192.168.52.148 ;
database=world;
basePath=d:\Resources
最后附上XMLParser的三个文件凑下篇幅:
/*
* UnityScript Lightweight XML Parser
* by Fraser McCormick (unityscripts@roguishness.com)
* http://twitter.com/flimgoblin
* http://www.roguishness.com/unity/
*
* You may use this script under the terms of either the MIT License
* or the Gnu Lesser General Public License (LGPL) Version 3.
* See:
* http://www.roguishness.com/unity/lgpl-3.0-standalone.html
* http://www.roguishness.com/unity/gpl-3.0-standalone.html
* or
* http://www.roguishness.com/unity/MIT-license.txt
*//* Usage:
* parser=new XMLParser();
* var node=parser.Parse("Foobar3");
*
* Nodes are Boo.Lang.Hash values with text content in "_text" field, other attributes
* in "@attribute" and any child nodes listed in an array of their nodename.
*
* any XML meta tags .. ?> are ignored as are comments
* any CDATA is bundled into the "_text" attribute of its containing node.
*
* e.g. the above XML is parsed to:
* node={ "example":
*[
*{ "_text":"",
*"value": [ { "_text":"Foobar", "@type":"String"}, {"_text":"3", "@type":"Int"}]
*}
*],
*"_text":""
*}
*
*/
XMLParser:
using System.Collections;
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= ']';
publicXMLNode Parse(string content)
{
XMLNode rootNode = new XMLNode();
rootNode["_text"] = "";
string nodeContents = "";
bool inElement = false;
bool collectNodeName = false;
bool collectAttributeName = false;
bool collectAttributeValue = https://www.it610.com/article/false;
bool quoted = false;
string attName ="";
string attValuehttps://www.it610.com/article/= "";
string nodeName = "";
string textValuehttps://www.it610.com/article/= "";
bool inMetaTag = false;
bool inComment = false;
bool inCDATA = https://www.it610.com/article/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 charif ((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) == " 0)
{
if (nodeName[0] == SLASH)
{
// close tag
if (textValue.Length > 0)
{
currentNode["_text"] += textValue;
}textValuehttps://www.it610.com/article/= "";
nodeName = "";
currentNode = parents.Pop();
}
else
{
if (textValue.Length > 0)
{
currentNode["_text"] += textValue;
}textValuehttps://www.it610.com/article/= "";
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 = https://www.it610.com/article/false;
if (attName.Length> 0)
{
if (attValue.Length > 0)
{
currentNode["@" + attName] = attValue;
}
else
{
currentNode["@" + attName] = true;
}
}i++;
currentNode = parents.Pop();
attName = "";
attValuehttps://www.it610.com/article/= "";
}
else if (!quoted && c == GT)
{
inElement = false;
collectAttributeName = false;
collectAttributeValue = https://www.it610.com/article/false;
if (attName.Length> 0)
{
currentNode["@" + attName] = attValue;
}attName = "";
attValuehttps://www.it610.com/article/= "";
}
else
{
if (collectAttributeName)
{
if (c == SPACE || c == EQUALS)
{
collectAttributeName = false;
collectAttributeValue = https://www.it610.com/article/true;
}
else
{
attName += c;
}
}
else if (collectAttributeValue)
{
if (c == QUOTE || c == QUOTE2)
{
if (quoted)
{
collectAttributeValue = false;
currentNode["@" + attName] = attValue;
attValuehttps://www.it610.com/article/= "";
attName = "";
quoted = false;
}
else
{
quoted = true;
}
}
else
{
if (quoted)
{
attValue += c;
}
else
{
if (c == SPACE)
{
collectAttributeValue = https://www.it610.com/article/false;
currentNode["@" + attName] = attValue;
attValuehttps://www.it610.com/article/= "";
attName = "";
}
}
}
}
else if (c == SPACE)
{}
else
{
collectAttributeName = true;
attName = "" + c;
attValuehttps://www.it610.com/article/= "";
quoted = false;
}
}
}
}
else
{
if (c == LT)
{
inElement = true;
collectNodeName = true;
}
else
{
textValue += c;
}
}
}
return rootNode;
}
}XMLNode:
C#代码
using System.Collections;
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;
}
}XMLNodeList:
C#代码
using System.Collections;
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;
}
}当然XMLParser最大的缺憾是不能写入,看需求吧!参考:①UnityScript Lightweight XML Parser: http://www.roguishness.com/unity/
推荐阅读