<?xml version="1.0" encoding="utf-8" ?>
<info>
<part code="N" name="信息速递">
<p1 code="a0" name="视点聚焦"></p1>
<p1 code="a1" name="专题报道"></p1>
<p1 code="a2" name="财经动态"></p1>
<p1 code="a3" name="产经动态"></p1>
<p1 code="a4" name="经济政策"></p1>
<p1 code="a5" name="国际专题"></p1>
</part>
<part code="I" name="商海资讯">
<p1 code="a0" name="经济观察"></p1>
<p1 code="a1" name="会展经济"></p1>
<p1 code="a2" name="产品技术"></p1>
<p1 code="a3" name="创业商机"></p1>
<p1 code="a4" name="技能培训"></p1>
<p1 code="a5" name="法律法规"></p1>
</part>
</info>
一、从XML数据到DataSet数据的变化
private void Page_Load(object sender, System.EventArgs e)
{
DataSet xds=new DataSet();
FileStream fsReadXml=new FileStream(Server.MapPath("XMLFile1.xml"),FileMode.OpenOrCreate,FileAccess.Read);
XmlTextReader myXmlReader=new XmlTextReader(fsReadXml);
xds.ReadXml(myXmlReader);
myXmlReader.Close();
DataTable xdt1=xds.Tables[0];
DataTable xdt2=xds.Tables[1];
string strName=xdt1.TableName;
string strName1=xdt2.TableName;
Response.Write(strName+" "+strName1+"<br>");//显示第一个节点和第二点节点的名字
string colName=xdt1.Columns[0].ColumnName;
string colName1=xdt1.Columns[1].ColumnName;
string colName2=xdt1.Columns[2].ColumnName;
Response.Write("1:"+colName+"2:"+colName1+"3:"+colName2+"<br>");
int xdt1rows=xdt1.Rows.Count;
int xdt1columns=xdt1.Columns.Count;
Response.Write("<br>row:"+xdt1.Rows.Count.ToString()+" column:"+xdt1.Columns.Count.ToString());
Response.Write("<br><br><br><br><br>");
Response.Write(xdt2.Rows.Count.ToString()+"========"+xdt2.Columns.Count.ToString());
Response.Write("??:"+xdt2.Columns[0].ColumnName.ToString()+"&"+xdt2.Columns[1].ColumnName.ToString()+"&"+xdt2.Columns[2].ColumnName.ToString());
}
private void Button1_Click(object sender, System.EventArgs e)
{
DataSet xds=new DataSet();
FileStream fsReadXml=new FileStream(Server.MapPath("XMLFile1.xml"),FileMode.OpenOrCreate,FileAccess.Read);
XmlTextReader myXmlReader=new XmlTextReader(fsReadXml);
xds.ReadXml(myXmlReader);
myXmlReader.Close();
this.DataGrid1.DataSource=xds.Tables[0].DefaultView;;
this.DataGrid1.DataBind();
}
private void Button2_Click(object sender, System.EventArgs e)
{
DataSet xds=new DataSet();
FileStream fsReadXml=new FileStream(Server.MapPath("XMLFile1.xml"),FileMode.OpenOrCreate,FileAccess.Read);
XmlTextReader myXmlReader=new XmlTextReader(fsReadXml);
xds.ReadXml(myXmlReader);
myXmlReader.Close();
this.DataGrid2.DataSource=xds.Tables[1].DefaultView;;
this.DataGrid2.DataBind();
}
代码分析:
上面这个例子:就是DataSet中有两个表,一个是以一级节点标签名为名的表,和一个以二级节点标签名为名的表。
这个实例主要是让读者明白从XML到DataSet之间数据的变化,从中可以看到这样的规律。每一级别的相同标签形成一个表,该表的名称就是该该标签的名称,如Part,P1等。
第一节点的内容在DataSet的表中的列名安排:
(1) 排列顺序列,列名组成方式为节点名_Id,如Part_Id.
(2) 节点内容列,列名组成方式为节点名_Text,有节点内容时无下级节点。
(3) 节点属性列,列名组成方式为节点属性名,如Code.
第二节点内容在DataSet中的表中的列名安排:
(1) 节点内容列,列名组成方式为节点名_Text。
(2) 节点属性列,列名组成方式为节点属性名,如二级Code。
(3) 关联属性列,列名组成方式为上级节点名_Id,如Part_Id.
依次类推。
二、通过DOM访问XML
XML的节点访问模式通常是通过DOM方法,该方法可以读取XML中的节点内容,然后将这些数据保存为XML文件。
XML结合XPATH对节点的调用
如果不使用XPath,则检索DOM中的一个或多个节点将需要大量导航代码。而使用XPath只需要一行代码。对于查找特定节点,应使用SelectSingleNode方法。如果有多个节点与搜索条件匹配,则SelectSingleNode按文档顺序从树的顶部向下导航,返回第一个与搜索条件匹配的节点。
单个节点:
XmlNode node=root.SelectSingleNode(Xpath 表达式)
若要将多个节点检索到节点集中,请使用SelectNodes方法。SelectNodes返回节点集,该节点集被放到XmlNodeList对象中。.NET已对XmlNodeList进行了枚举以提供foreach语句功能,这样可以对XmlNodeList中的节点进行访问。
多个节点:
XmlNodeList nodelist=root.SelectNodes(Xpath 表达式)
另外,使用XPath能方便地对XML文件的节点进行修改。
如下:
private void Page_Load(object sender, System.EventArgs e)
{
string filename=Server.MapPath("XMLFile1.xml");
//Response.Write(filename);
XmlDocument doc=new XmlDocument();
doc.Load(filename);
XmlNodeList nodeList;
XmlNode root=doc.DocumentElement;
nodeList=root.SelectNodes("/info/part/p1[@code='a0']");
foreach(XmlNode book in nodeList)
{
book.InnerText="100";
}
doc.Save(filename);
}
表达式的含义
XmlNode node=root.SelectSingleNode(“/info/part[@code=’N’]/p1[@code=’a1’]”)
该表达式的含义为:从XML中选择层次机构为/info/part/p1的节点,其中要求part节点的code属性的值为N,而p1节点的code属性的值为a1。把这个规则跟上面的XML文件对照,就能发现符合条件的数据只有<p1 code=”a1” name=”专题报道”></p1>,因此使用该Xpath对“专题报道”所在节点进行调用是合适的。
另外在对XML节点进行调用时,通过SelectNodes、SelectSingleNode调用出来的节点可以包含子级节点。因此该节点调用出来后,还可以对它是否有子级节点以及子级节点的类型进行判断,判断语句如下:
Bool HasChileNode=Node1.HasChildNodes;
判断是否有子级节点,返回数据类型为bool。
String NodeType_Name=Node1.ChildNodes[0].NodeType.ToString();
判断子级节点的类型,有Element、Text等类型,当该类型为Element时表示该节点是如下形式:
<part code="N" name="信息速递">
<p1 code="a0" name="视点聚焦"></p1>
<p1 code="a1" name="专题报道"></p1>
<p1 code="a2" name="财经动态"></p1>
<p1 code="a3" name="产经动态"></p1>
<p1 code="a4" name="经济政策"></p1>
<p1 code="a5" name="国际专题"></p1>
</part>
而当该类型为Text时,表示如下节点:
<p1 code="a0" name="视点聚焦">100</p1>
根据以上知识做一个例子
private void Page_Load(object sender, System.EventArgs e)
{
string filename=Server.MapPath("XMLFile1.xml");
//使用DataSet
DataSet ds=new DataSet();
ds.ReadXml(filename);
this.DataGrid1.DataSource=ds.Tables["part"].DefaultView;
this.DataGrid1.DataBind();
this.DataGrid2.DataSource=ds.Tables["p1"].DefaultView;
this.DataGrid2.DataBind();
//使用DOM
XmlDocument doc=new XmlDocument();
doc.Load(filename);
XmlNode root=doc.DocumentElement;
//XmlNodeList的使用
XmlNodeList nodeList=root.SelectNodes("/info/part/p1[@code='a0']");
Response.Write("使用XmlNodeList调用节点:<br/>");
foreach(XmlNode part in nodeList)
{
Response.Write(part.Attributes["name"].Value+" ");
}
//使用Xpath对节点进行控制
XmlNode node1=root.SelectSingleNode("/info/part[@code='N']");
Response.Write("<hr/>通过SelectSingleNode对单个节点的调用:<br/>");
Response.Write(node1.Attributes["name"].Value.ToString()+">>");
//HasChildNodes判断是否有子节点,NodeType判断节点类型
bool haschild=node1.HasChildNodes;
string childtype=node1.ChildNodes[0].NodeType.ToString();
// string childtype1=node1.ChildNodes[1].NodeType.ToString();
// string childtype2=node1.ChildNodes[2].NodeType.ToString();
// Response.Write("1:"+childtype+" 2:"+childtype1+" 3:"+childtype2);
if(haschild&&(childtype=="Element"))
{
XmlNode node2=root.SelectSingleNode("/info/part[@code='N']/p1[@code='a0']");
Response.Write(node2.Attributes["name"].Value.ToString()+">>");
}
for(int i=0;i<node1.ChildNodes.Count;i++)
{
node1.ChildNodes[i].InnerText="hoho"+i;
}
doc.Save(filename);
}
刷新后的结果: