`

C# 轻量级解析XML——XMLParser

阅读更多

    C# 轻量级解析XML——XMLParser

       记得之前写过一篇关于XML解析的博客(猛点查看),之前是因为发现Xpath这个类似SQL语句的字符串解析XML,觉得很惊奇,遂有了那篇文章。用XMLParser解析XML文件,是因为工作Unity发布WinPhone版本是不支持System.xml这个类库,这里的确有点想吐槽下(Microsoft在自家院里怎么没有做兼容)。所以我就google下,才找到了XMLparser这个类库(其实就三个.cs文件)。

       这里介绍下XMLParser的原理,XMLParser应就三个类文件 XMLParser,XMLNode,XMLNodeList,顾名思义,XMLParser就是解析XML的实现类(基于字符匹配解析的,具体细节可以看代码,我是没心思看这个了,太绕了),XMLNode就是将解析出来的“项”存储为XMLNode,其实就是一个Hashtable,XMLNodeList就不用多说了。查询的时候就是需要查询项的“路径”字符串传入XMLNode(Hashtable)查找返回。

    写到这里突然想到写这篇博客的另外一个理由:XMLParser这个类库是我找到的,但是是给项目其他同事用的,然后我那个同事一直说解析不到,妈蛋,会不会用呀,然后我就无语写了几行例子教程。

    所以直接附上这几行教程:

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" />
 </items>

 得到的解析结果是 

server=192.168.52.148 ;  database=world;  basePath=d:\Resources

 

 

最后附上XMLParser的三个文件凑下篇幅:

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("<example><value type=\"String\">Foobar</value><value type=\"Int\">3</value></example>");
 * 
 * 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":""
 *     }
 *		  
 */

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    = ']';
	
	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;
	}
}

 XMLNode:

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:

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;
	}
}

 

        就是这么简单(代码可以粘贴复制下来琢磨),我觉得最爽的是不用看C# 微软的那套api,然后使用起来还有跟剥笋一样一层一层进入,挺费事,一点快感都没有。当然XMLParser最大的缺憾是不能写入,看需求吧!

 

        最后还是说下自己的感悟:很久没有写博客了,虽然写的东西都很渣,但是我觉得写博客,可以给自己一个整理的过程,堆积了一堆东西没有写,最近项目比较闲,所以今天有用了会XMLParser,就果断了。

        如果您对D.S.Qiu有任何建议或意见可以在文章后面评论,或者发邮件(gd.s.qiu@gmail.com)交流,您的鼓励和支持是我前进的动力,希望能有更多更好的分享。

        转载请在文首注明出处:http://dsqiu.iteye.com/admin/blogs/1964401

更多精彩请关注D.S.Qiu的博客和微博(ID:静水逐风)

 

参考:

①UnityScript Lightweight XML Parser: http://www.roguishness.com/unity/

 

1
0
分享到:
评论
1 楼 liuweihug 2014-05-07  
C# Linq使用XDocument读取Xml文件并形成结构树数据(json) 
http://www.suchso.com/projecteactual/Csharp-Linq-XDocument-Xml-File-Tree-Data.html

相关推荐

    基于 OpenCV 的魔兽世界钓鱼机器人

    基于 OpenCV 的魔兽世界钓鱼机器人

    供应链管理中信息共享问题的研究.docx

    供应链管理中信息共享问题的研究

    青春文学中的爱情观呈现.doc

    青春文学中的爱情观呈现

    分布式光伏储能系统的优化配置方法 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    Delphi 12.3 控件之XLSReadWriteII6.02.01.7z

    XLSReadWriteII6.02.01.7z

    图解系统-小林coding-v1.0.rar

    图解系统-小林coding-v1.0

    【光伏功率预测】基于EMD-PCA-LSTM的光伏功率预测模型 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    漫画作品与乌托邦理想追求.doc

    漫画作品与乌托邦理想追求

    江苏建筑消防设施维护保养规程.rar

    江苏建筑消防设施维护保养规程.rar

    基于交互式可视化的Transformer模型注意机制探索工具-DODRIO及其应用

    内容概要:论文介绍了一款名为DODRIO的交互式可视化工具,帮助自然语言处理(NLP)研究人员和从业者解析基于转换器架构的语言模型内部工作机理。DODRIO整合了概述图与详尽视图,支持用户比较注意力权重与其输入文本的句法结构和语义特征。具体而言,它包含了依赖关系视图(Dependency View)、语义关注图(Semantic Attention Graph)以及注意力头概览(Attention Head Overview),并利用不同的图形展示方法使复杂的多层多头转换器模型中的注意力模式更容易理解和研究。 适用人群:适用于从事深度学习、自然语言处理的研究人员和技术从业者;尤其适合对基于变换器架构的大规模预训练语言模型感兴趣的开发者们。 使用场景及目标:DODRIO用于探索转换器模型各层级之间的联系、验证已有研究成果,同时激发新假设形成。具体使用时可以选择特定数据集中的句子作为样本输入,观察不同注意力机制如何响应文本内容的变化。此外,还可以用来对比精简版本DistilBERT的表现,评估其相对全量模型BERT的优势与不足。 其他说明:DODRIO为开源项目,提供web端实施方式,使得

    基于机器学习的疾病数据集分析

    该代码使用scikit-learn的乳腺癌数据集,完成分类模型训练与评估全流程。主要功能包括:数据标准化、三类模型(逻辑回归、随机森林、SVM)的训练、模型性能评估(分类报告、混淆矩阵、ROC曲线)、随机森林特征重要性分析及学习曲线可视化。通过`train_test_split`划分数据集,`StandardScaler`标准化特征,循环遍历模型进行统一训练和评估。关键实现细节包含:利用`classification_report`输出精确度/召回率等指标,绘制混淆矩阵和ROC曲线量化模型效果,随机森林的特征重要性通过柱状图展示,学习曲线分析模型随训练样本变化的拟合趋势。最终将原始数据和预测结果保存为CSV文件,便于后续分析,并通过matplotlib进行多维度可视化比较。代码结构清晰,实现了数据处理、模型训练、评估与可视化的整合,适用于乳腺癌分类任务的多模型对比分析。

    数字化智慧园区建设实施PPT(43页).pptx

    在智慧城市建设的大潮中,智慧园区作为其中的璀璨明珠,正以其独特的魅力引领着产业园区的新一轮变革。想象一下,一个集绿色、高端、智能、创新于一体的未来园区,它不仅融合了科技研发、商业居住、办公文创等多种功能,更通过深度应用信息技术,实现了从传统到智慧的华丽转身。 智慧园区通过“四化”建设——即园区运营精细化、园区体验智能化、园区服务专业化和园区设施信息化,彻底颠覆了传统园区的管理模式。在这里,基础设施的数据收集与分析让管理变得更加主动和高效,从温湿度监控到烟雾报警,从消防水箱液位监测到消防栓防盗水装置,每一处细节都彰显着智能的力量。而远程抄表、空调和变配电的智能化管控,更是在节能降耗的同时,极大地提升了园区的运维效率。更令人兴奋的是,通过智慧监控、人流统计和自动访客系统等高科技手段,园区的安全防范能力得到了质的飞跃,让每一位入驻企业和个人都能享受到“拎包入住”般的便捷与安心。 更令人瞩目的是,智慧园区还构建了集信息服务、企业服务、物业服务于一体的综合服务体系。无论是通过园区门户进行信息查询、投诉反馈,还是享受便捷的电商服务、法律咨询和融资支持,亦或是利用云ERP和云OA系统提升企业的管理水平和运营效率,智慧园区都以其全面、专业、高效的服务,为企业的发展插上了腾飞的翅膀。而这一切的背后,是大数据、云计算、人工智能等前沿技术的深度融合与应用,它们如同智慧的大脑,让园区的管理和服务变得更加聪明、更加贴心。走进智慧园区,就像踏入了一个充满无限可能的未来世界,这里不仅有科技的魅力,更有生活的温度,让人不禁对未来充满了无限的憧憬与期待。

    Matlab实现BO贝叶斯优化-Transformer-GRU多特征分类预测的详细项目实例(含完整的程序,GUI设计和代码详解)

    内容概要:本文档介绍了基于MATLAB实现的贝叶斯优化(BO)、Transformer和GRU相结合的多特征分类预测项目实例,涵盖了详细的程序设计思路和具体代码实现。项目旨在应对数据的多样性与复杂性,提供一种更高效的多特征数据分类解决方案。文档主要内容包括:项目背景与意义,技术难点与解决方案,具体的实施流程如数据处理、模型构建与优化、超参数调优、性能评估以及精美的GUI设计;详细说明了Transformer和GRU在多特征数据分类中的应用及其与贝叶斯优化的有效结合,强调了其理论与实际应用中的价值。 适合人群:具备一定机器学习和MATLAB编程基础的研发人员,特别是从事多维数据处理与预测工作的专业人士和技术爱好者。 使用场景及目标:① 适用于金融、医疗、交通等行业,进行复杂的多维数据处理和预测任务;② 提升现有分类任务中复杂数据处理的准确度和效率,为各行业提供智能预测工具,如金融市场预测、患者病情发展跟踪、交通流量管理等。 其他说明:本文档包含了丰富的实战案例和技术细节,不仅限于模型设计本身,还涉及到数据清洗、模型优化等方面的知识,帮助使用者深入理解每一步骤背后的原理与实现方法。通过完整的代码样例和GUI界面设计指导,读者可以从头到尾跟随文档搭建起一套成熟的分类预测系统。

    Hive sql练习题,只是参考作用

    大数据的sql练习题,初级中级高级

    基于自注意力机制的序列转换模型-Transformer的提出及其应用

    内容概要:论文介绍了名为Transformer的新网络架构,它完全基于自注意力机制,在不使用递归或卷积神经网络的情况下建模输入与输出之间的全局依赖关系,尤其适用于长文本处理。通过多头自注意力层和平行化的全连接前馈网络,使得在机器翻译任务上的表现优于当时最佳模型。具体地,作者用此方法实现了对英语-德语和英语-法语翻译、句法解析等任务的高度并行化计算,并取得显著效果。在实验方面,Transformer在较短训练时间内获得了高质量的翻译结果以及新的单一模型基准。除此之外,研究人员还探索了模型变体的效果及其对于不同参数变化时性能的变化。 适用人群:从事自然语言处理领域的研究者、工程师、学生,熟悉深度学习概念尤其是编码器-解码器模型以及关注模型创新的人士。 使用场景及目标:主要适用于序列到序列(seq2seq)转换任务如机器翻译、语法分析、阅读理解和总结等任务的研究和技术开发;目标在于提高计算效率、缩短训练时间的同时确保模型性能达到或超过现有技术。 其他说明:本文不仅提出了一个新的模型思路,更重要的是展示了自注意力机制相较于传统LSTM或其他方式所拥有的优势,例如更好地捕捉远距离上下文关系的能力

    【故障诊断】一种滚动体轴承或齿轮的重复瞬态提取方法研究 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    用于平抑可再生能源功率波动的储能电站建模及评价 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    使用 KTH 数据集进行人类行为识别 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    【深度学习】基于计算机视觉的自动驾驶应用 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    自己写的远控木马,欢迎各位大佬改善

    自己写的远控木马,欢迎各位大佬改善

Global site tag (gtag.js) - Google Analytics