由于关于XML的知识有较多的学习资料,又鉴于本人的知识实在有限,所以本文旨在将我前一段在工作中遇到的问题和积累的一些经验和大家分享一下。
XML(Extensible Markup Language)是可扩展标记语言的缩写,它是由W3C工作组定义的一种标记语言。
XML独立于具体的操作平台和应用系统,具有很强的可重用性。
XML提供了一种结构化的数据表示方式,并将文档结构于显示内容分开。此外,XML还允许各种不同的专业与自己的特定领域有关的标记语言,使数据从描述和过程中分离出来。
XML允许以最合适的输出格式好用于应用程序的格式来传递内容。只要应用程序都支持XML,就可以在程序间无缝的交换数据。
允许用户创建自己的可被用于应用程序的可扩展的标志集,描述的精度可以由用户自己定义。
XML的数据是完全基于文档的,传输速度快,并且几乎所有的系统都能接收和理解XML数据。
C#为操作XML数据提供了相当多简单易行的方法,而且也有XML与数据库间直接转换的方法,但是由于是第一次接触这方面的知识,为了更加熟悉有关XML的基本知识,所以我采用的是最为基础的循环读元素和属性的方法。
这次的系统的表间关系相对比较复杂,对操作的限制也比较大。另外这次使用的XML文档格式是用属性来存储数据,而与大多数书籍上的参考资料不同,这些给我带来了一些干扰。个人认为两种存储方法各有优点,用属性存储数据给人感觉比较简洁,但数据间关系不够清晰,而且操作比较繁琐。而以元素形式存储则略显臃肿。
在实际操作中,我使用的是XMLReader类的派生类XMLTextReader类读取XML文档中的数据,其中提取了一些我认为常用的属性和方法:
属性/方法 |
|
AttributeCount |
当前结点上的属性数 |
Name |
结点或属性名 |
Value |
结点或属性值 |
has Attribute |
当前结点是否有属性,true或false |
GetAttribute() |
获得属性值 |
Read( ) |
读取下一结点 |
MoveToAttribute() |
移动的指定结点 |
MoveToNextAttribute() |
移动到下一结点 |
在功能的实现方面,我使用的是最原始的while循环嵌套加if判断的方式确保循环到每一层、每一结点及每一属性,并生成sql语句完成数据库操作,感觉上代码比较臃肿,并且方法比较原始笨拙,但对XML的相关知识理解有了进一步加深。
个人理解,由于XML灵活性,可以自己定义标签的名称,这就为对其操作带来了很多简洁而灵活的方法,在深刻了解了XML文档结构后对操作代码进行重构,可以极大的减少代码量,提高可读性。
由于看到了使用的方法比较原始而且可读性不高,我也在积极的修改代码,争取应用C#类库中比较简单实用的类和方法,改善代码,提高可读性。
<?xml version="1.0" encoding="utf-8"?>
<Databases>
<Database Name="aa" CheckinTime="" UpdateTime="" version="" />
<Tables>
<Table Name="aaa1" CheckinTime="" UpdateTime="" version="" />
<Columns>
<Column Name="aaa1a" CheckinTime="" UpdateTime="" version="" />
</Columns>
<Table Name="aaa2" CheckinTime="" UpdateTime="" version="" />
<Columns>
<Column Name="aaa2a" CheckinTime="" UpdateTime="" version="" />
</Columns>
</Tables>
</Databases>
以上是一段简单的XML文档,我们需要按照Database—>Table—>Column的顺序逐层的遍历所有数据。
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace _
{
class Program
{
static void Main(string[] args)
{
XmlTextReader rd = new XmlTextReader("C:\\Documents and Settings\\Administrator.D4D1C4378A72451\\桌面\\1.xml"); //读取指定路径的文件
rd.WhitespaceHandling = WhitespaceHandling.None;
while (rd.Read()) //最外层循环,遍历所有Database
{
if (rd.Name != "Database") //找到首个Database结点
continue;
for (int i = 0; i < rd.Depth; i++)
{
Console.Write("\t");
}
Console.Write("<");
for (int i = 0; i < rd.AttributeCount; i++)
{
Console.Write("{0}='{1}'", rd.Name, rd.GetAttribute(i));
}
Console.WriteLine("/>");
while (rd.Read() && !(rd.NodeType == XmlNodeType.EndElement && rd.Name == "Tables")) //遍历提取所有的Table中的数据
{
if (rd.Name != "Table")
continue;
for (int i = 0; i < rd.Depth; i++)
{
Console.Write("\t");
}
Console.Write("<");
for (int i = 0; i < rd.AttributeCount; i++)
{
Console.Write("{0}='{1}'", rd.Name, rd.GetAttribute(i));
}
Console.WriteLine("/>");
while (rd.Read() && !(rd.NodeType == XmlNodeType.EndElement && rd.Name == "Columns")) //遍历提取所有的Column中的数据
{
if (rd.Name != "Column")
continue;
for (int i = 0; i < rd.Depth; i++)
{
Console.Write("\t");
}
Console.Write("<");
for (int i = 0; i < rd.AttributeCount; i++)
{
Console.Write("{0}='{1}'", rd.Name, rd.GetAttribute(i));
}
Console.WriteLine("/>");
}
}
}
}
}
}
这是一段遍历上面XML文档的代码,运行结果如下图。提取了所有数据,便可以进行更新数据库。