春夏秋冬

一年四季...春夏秋冬...

  博客园 :: 首页 :: 联系 :: 订阅 订阅 :: 管理
  7 Posts :: 1 Stories :: 2 Comments :: 0 Trackbacks

2006年12月21日 #

MD5

public static string MD5Encrypt(string  pToEncrypt,  string  sKey)
  { 
   DESCryptoServiceProvider  des  =  new  DESCryptoServiceProvider(); 
   byte[]  inputByteArray  =  Encoding.Default.GetBytes(pToEncrypt); 
   des.Key  =  ASCIIEncoding.ASCII.GetBytes(sKey); 
   des.IV  =  ASCIIEncoding.ASCII.GetBytes(sKey); 
   MemoryStream  ms  =  new  MemoryStream(); 
   CryptoStream  cs  =  new  CryptoStream(ms,  des.CreateEncryptor(),CryptoStreamMode.Write); 
   cs.Write(inputByteArray,  0,  inputByteArray.Length); 
   cs.FlushFinalBlock(); 
   StringBuilder  ret  =  new  StringBuilder(); 
   foreach(byte  b  in  ms.ToArray()) 
   { 
    ret.AppendFormat("{0:X2}",  b); 
   } 
   ret.ToString(); 
   return  ret.ToString(); 
  }

  ///MD5解密
  public static  string MD5Decrypt(string  pToDecrypt,  string  sKey)
  {
   DESCryptoServiceProvider  des  =  new  DESCryptoServiceProvider(); 

   byte[]  inputByteArray  =  new  byte[pToDecrypt.Length  /  2]; 
   for(int  x  =  0;  x  <  pToDecrypt.Length  /  2;  x++) 
   { 
    int  i  =  (Convert.ToInt32(pToDecrypt.Substring(x  *  2,  2),  16)); 
    inputByteArray[x]  =  (byte)i; 
   } 

   des.Key  =  ASCIIEncoding.ASCII.GetBytes(sKey); 
   des.IV  =  ASCIIEncoding.ASCII.GetBytes(sKey); 
   MemoryStream  ms  =  new  MemoryStream(); 
   CryptoStream  cs  =  new  CryptoStream(ms,  des.CreateDecryptor(),CryptoStreamMode.Write); 
   cs.Write(inputByteArray,  0,  inputByteArray.Length); 
   cs.FlushFinalBlock(); 

   StringBuilder  ret  =  new  StringBuilder(); 
            
   return  System.Text.Encoding.Default.GetString(ms.ToArray());

posted @ 2006-12-21 11:23 春夏秋冬 阅读(28) | 评论 (0)编辑

2006年12月6日 #

     摘要: 原文 | 下载本教程中的编码例子 | 下载本教程的英文PDF版导言作为web开发人员,我们的生活围绕着数据操作。我们建立数据库来存储数据,写编码来访问和修改数据,设计网页来采集和汇总数据。本文是研究在ASP.NET 2.0中实现这些常见的数据访问模式之技术的长篇系列教程的第一篇。我们将从创建一个软件框架开始,这个框架的组成部分包括一个使用强类型的DataSet的数据访问层(DAL),一个实施用户定...  阅读全文
posted @ 2006-12-06 15:58 春夏秋冬 阅读(146) | 评论 (0)编辑

2006年12月1日 #

SQLDMO(SQL Distributed Management Objects,SQL分布式管理对象)封装了Microsoft SQL Server数据库中的对象。SQLDMO是Microsoft SQL Server中企业管理器所使用的应用程序接口,所以它可以执行很多功能,其中当然也包括对数据库的备份和恢复。

      SQLDMO由Microsoft SQL Server自带的SQLDMO.dll提供,由于SQLDMO.dll是一个COM对象,所以大家在用之前必须在.NET项目中添加对它的引用,如下图所示:

下面是用C#语言书写的用于Microsoft SQL Server数据库备份和恢复的类:

using System;

namespace DbService
{
 /// <summary>
 /// DbOper类,主要实现对Microsoft SQL Server数据库的备份和恢复
 /// </summary>
 public sealed class DbOper
 {
  /// <summary>
  /// DbOper类的构造函数
  /// </summary>
  private DbOper()
  {
  }

  /// <summary>
  /// 数据库备份
  /// </summary>
  public static void DbBackup()
  {
   try
   {
    SQLDMO.Backup oBackup = new SQLDMO.BackupClass();
    SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
    oSQLServer.LoginSecure = false;
    oSQLServer.Connect("localhost", "sa", "1234");
    oBackup.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database;
    oBackup.Database = "Northwind";
    oBackup.Files = @"d:\Northwind.bak";
    oBackup.BackupSetName = "Northwind";
    oBackup.BackupSetDescription = "数据库备份";
    oBackup.Initialize = true;
    oBackup.SQLBackup(oSQLServer);
   }
   catch
   {
    throw;
   }
  }

  /// <summary>
  /// 数据库恢复
  /// </summary>
  public static void DbRestore()
  {
   try
   {
    SQLDMO.Restore oRestore = new SQLDMO.RestoreClass();
    SQLDMO.SQLServer oSQLServer = new SQLDMO.SQLServerClass();
    oSQLServer.LoginSecure = false;
    oSQLServer.Connect("localhost", "sa", "1234");
    oRestore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database;
    oRestore.Database = "Northwind";
    oRestore.Files = @"d:\Northwind.bak";
    oRestore.FileNumber = 1;
    oRestore.ReplaceDatabase = true;
    oRestore.SQLRestore(oSQLServer);
   }
   catch
   {
    throw;
   }
  }
 }
}

来源:CSDN

posted @ 2006-12-01 14:15 春夏秋冬 阅读(51) | 评论 (0)编辑

2006年11月29日 #

2006-11-29下午,我接受了一个光荣的任务,去给一个人装系统去,本来一想也没什么,但一听说他装98我郁闷了,虽然我长装系统但一般都是光盘启动的2000或xp,下午那个人给我打电话了,他没有盘,我也没有,马上从网上下了一个98,走人,路上无话,我们进入正题,我到了,一个不错的小区,我进门,居然没拦我,哈哈,(可能看我象有钱人),由于没带手机,很久才到他家,中间的周折就别提了,那就不爽,进去后,说硬件低,必须装98,我哪装过那个呀?反正知道用光盘起,先是是,碰碰运气,哈哈,不巧不成书,没起来,靠,这可怎么办?????

 我想问的第一个问题出来了 1,各位老大,98能用光盘启动吗?第二版的,谢谢了,

我一看不好,怎么办,不要紧幸亏走的时候拿了个启动盘(不是软盘,软盘的没用过),是番茄花园的,我启动进去,然后运用我不怎么熟悉的dos命令,xxxxxxx到了光盘,然后插入98盘,我记着是cd winnt然后就能装了,可?????/居然没有这个目录,汗了,赶紧打电话,找高手,他说直接运行setup,我一运行,怎么又开始检测硬盘了

 我想问的第二个问题出来了 2,各位老大,98在dos下安装必须检测硬盘吗?能不能越过呀?

我就一路运行,好象要修补硬盘的什么错误,几个盘下来,一看c盘不能修补,又退出来了,总不能进入安装界面,这下完了,没办法了,干脆一不做二不修,装2000,这可是我的拿手活,format c:然后咔咔完,但驱动怎么办?他家别提了,住的比较好,却用猫上网,说实在的,我没用过那个,草,茫然了...........................,把猫打开,检测到了硬件,我装了驱动,能用了,太好了,拨了下,可以了,赶紧下驱动,一看显卡是nvidia的,就下了个,对于硬件驱动,我不是很理解,芯片和牌子什么的??有点蒙,声卡是ac97,这个代表什么呀?我一查ac97,分太多种了,他究竟是什么呀?

 我想问的第三个问题出来了 2,各位老大,这个驱动怎么看呀?是看芯片呀?还是看名字?好象不管什么名字,芯片对了就行是吧?急需解决。。。也想找个人问问,驱动老装不上,也不是办法呀


我下了几个ac97的,一装居然合适了,我想这下好了,就重新起了电脑,我草,一起来,一个驱动没装上,猫的都没了

我想问的第四个问题出来了 2,各位老大,这个猫在98下,据说一用就好,为什么在2000下就垃圾了,难道也是他自己带的驱动盘不好用?我看了支持的系统 9x,Nt,我想问下,这个nt包括2000和xp不??难道驱动版本不行了??


连显卡声卡都没好用,真是头疼呀,这个驱动。。。。。。。。。
说是短,一晃在客户这都晚上7点了,一点东西没弄好,客户也不好意思了,说回去跟同事商量下,明天在来,我想好吧,告辞回家,到家快9点了,真是不痛快呀。而家里还有许多东西没有做,一想脑袋都疼,明天打算跟经理说去,我是没办法了,最近也不知道怎么了,头都大忙的,赶紧睡觉了,否则明天又要迟到了,最近老迟到...........
posted @ 2006-11-29 22:39 春夏秋冬 阅读(28) | 评论 (0)编辑

2006年11月28日 #

今天兴致来了,本来想写点东西,但由于手里有点活,郁闷...,还的做??????????,最近感觉有点累,但决定写点东西,记录下这段经历,毕竟青春匆匆而过呀,一晃,我快30了,太可怕了........希望大家能长来捧场。

 还有我家的破电脑太慢了,要风了,运行1.1+xp都慢,别说2.0了,只能在公司用2.0呀,有买条子的想法了,但一个512的,我感觉有点贵,哎!!!!,又说到点子上了,穷呀,我家是256的,但速度感觉光光慢,没办法我家的主板就2个槽子,2个128,xxxxxxxxxxxxxx,很把,我想买个512,还必须下岗一个128,还是公司的好,夜晶的显示器,512内存,奔IV 3.6感觉就是爽,真想下班的时候把电脑抱家去,不写了,赶紧工作把,不然连泡面都吃不上了,谢谢各位捧场......,以后我会写点东西,呵呵

posted @ 2006-11-28 22:56 春夏秋冬 阅读(29) | 评论 (2)编辑

wmimgmt.msc----------打开windows管理体系结构(wmi)
wupdmgr----------windows更新程序
write----------写字板
winmsd----------系统信息
wiaacmgr----------扫描仪和照相机向导
winchat----------xp自带局域网聊天
mem.exe----------显示内存使用情况
msconfig.exe----------系统配置实用程序
mplayer2----------简易widnowsmediaplayer
mspaint----------画图板
mstsc----------远程桌面连接
mplayer2----------媒体播放机
magnify----------放大镜实用程序
mmc-----------打开控制台
mobsync----------同步命令
dxdiag----------检查directx信息
drwtsn32----------系统医生
devmgmt.msc----------设备管理器
dfrg.msc----------磁盘碎片整理程序
diskmgmt.msc----------磁盘管理实用程序
dcomcnfg----------打开系统组件服务
ddeshare----------打开dde共享设置
dvdplay----------dvd播放器
netstopmessenger----停止信使服务
netstartmessenger---开始信使服务
notepad----------打开记事本
nslookup----------网络管理的工具向导
ntbackup----------系统备份和还原
narrator----------屏幕“讲述人”
ntmsmgr.msc----------移动存储管理器
ntmsoprq.msc----------移动存储管理员操作请求
netstat-an---------(tc)命令检查接口
syncapp----------创建一个公文包
sysedit----------系统配置编辑器
sigverif----------文件签名验证程序
sndrec32----------录音机
shrpubw----------创建共享文件夹
secpol.msc----------本地安全策略
syskey----------系统加密,一旦加密就不能解开,保护windowsxp系统的双重密码
services.msc----------本地服务设置
sndvol32----------音量控制程序
sfc.exe----------系统文件检查器
sfc/scannow----------windows文件保护
tsshutdn----------60秒倒计时关机命令
tourstart----------xp简介(安装完成后出现的漫游xp程序)
taskmgr----------任务管理器
eventvwr----------事件查看器
eudcedit----------造字程序
explorer----------打开资源管理器
packager----------对象包装程序
perfmon.msc----------计算机性能监测程序
progman----------程序管理器
regedit.exe----------注册表
rsop.msc----------组策略结果集
regedt32----------注册表编辑器
rononce-p---------15秒关机
regsvr32/u*.dll----停止dll文件运行
regsvr32/uzipfldr.dll--取消zip支持
cmd.exe----------cmd命令提示符
chkdsk.exe----------chkdsk磁盘检查
certmgr.msc----------证书管理实用程序
calc------------启动计算器
charmap----------启动字符映射表
cliconfg----------sqlserver客户端网络实用程序
clipbrd----------剪贴板查看器
conf-----------启动netmeeting
compmgmt.msc----------计算机管理
cleanmgr----------垃圾整理
ciadv.msc----------索引服务程序
osk-----------打开屏幕键盘
odbcad32----------odbc数据源管理器
oobe/msoobe/a-------检查xp是否激活
lusrmgr.msc----------本机用户和组
logoff----------注销命令
iexpress----------木马捆绑工具,系统自带
nslookup----------ip地址侦测器
fsmgmt.msc----------共享文件夹管理器
utilman----------辅助工具管理器
gpedit.msc----------组策略
FDISK/MBR----------------(将硬盘主引导程序直接重写)
GPEDIT.MSC---------------(在运行中打开计算机管理器)
MSCONFIG-----------------(在运行中打开

posted @ 2006-11-28 22:47 春夏秋冬 阅读(240) | 评论 (0)编辑

Dom访问Xml
一.Xml文件格式.
二.概述.
三.几种操作.
3.1添加...
3.2 修改...
3.3 删除...
3.4 复制到另一xml
3.5 除全部...
四.补充.
五.Xpath语法.
5.1 比较常见的...
5.1.1 选择所有的该类元素...
5.1.2 有条件的选择元素...
5.1.3 选择包含有某属性的元素...
5.1.4 选择包含有属性的元素...
5.1.5 选择属性值为**的元素...
5.2 以下是我从网上摘抄下来的。...
5.2.1 文档一...
5.2.2 文档二...

Dom访问Xml

在程序中访问进而操作XML文件一般有两种模型,分别是使用DOM(文档对象模型)和流模型。下面是我的学习笔记,主要是学习怎样用Dom访问Xml。


一.Xml文件格式

以下是用到的xml文件,名为contact.xml

<?xml version="1.0" encoding="utf-8"?>
<xmltt>
  <ContactDetails>
    <Contact>
      <Name>
        <First>luo</First>
        <Last>luo</Last>
      </Name>
      <Note>luoandluo</Note>
    </Contact>
  </ContactDetails>
</xmltt>

二.概述

DOM的好处在于它允许编辑和更新XML文档,可以随机访问文档中的数据,可以使用XPath查询,但是,DOM的缺点在于它需要一次性的加载整个文档到内存中,对于大型的文档,这会造成资源问题。流模型很好的解决了这个问题,因为它对XML文件的访问采用的是流的概念,也就是说,任何时候在内存中只有当前节点,但它也有它的不足,它是只读的,仅向前的,不能在文档中执行向后导航操作。(不好意思,都是抄的:),说理解吗,也是有的。

三.几种操作

3.1添加

string strXmlPath;
strXmlPath = Server.MapPath("contact.xml");
XmlDocument xDoc = new XmlDocument();
xDoc.Load(strXmlPath);
XmlElement xEle = null;

//首先查找是否已经存在要添加
xEle = (XmlElement)xDoc.SelectSingleNode(string.Format("//Name[First='{0}' and Last='{1}']",FirstName.Text,LastName.Text));

if (xEle!=null)  //已经存在
{
Label3.Text = "already exist";
}
else             //不存在,可以添加
{
XmlDocumentFragment xDocFrag = xDoc.CreateDocumentFragment();
XmlElement xContact = xDoc.CreateElement("Contact");
XmlElement xName = xDoc.CreateElement("Name");
XmlElement xFirst = xDoc.CreateElement("First");
xFirst.InnerText = FirstName.Text;
XmlElement xLast = xDoc.CreateElement("Last");
xLast.InnerText = LastName.Text;
xName.AppendChild(xFirst);
xName.AppendChild(xLast);
XmlElement xNote = xDoc.CreateElement("Note");
xNote.InnerText = FirstName.Text+"and"+LastName.Text;
xContact.AppendChild(xName);
xContact.AppendChild(xNote);
xDocFrag.AppendChild(xContact);
XmlNode xRoot = null;
xRoot = xDoc.SelectSingleNode("//ContactDetails");  //ContactDetails

if (xRoot!=null)
{
//xRoot.AppendChild(xDocFrag.FirstChild);// 加在最后
xRoot.PrependChild(xDocFrag.FirstChild);  //加在最前,做为第一个子节点
    //还有InsertBefore,InsertAfter(new,old)
    xDoc.Save(strXmlPath);
Label3.Text = "add sucess";  //
}
else
{
Label3.Text = "add failed";
}

3.2 修改

string str = Server.MapPath("contact.xml");
XmlDocument xDoc = new XmlDocument();
xDoc.Load(str);
XmlElement xEle = null;

//查看要修改的元素是否存在

xEle = (XmlElement)xDoc.SelectSingleNode(string.Format("//Name[First='{0}' and Last='{1}']",FirstName.Text,LastName.Text));
if (xEle==null)  //不存在
{
Label5.Text = "no exist";
}
else    //存在
{
//下面是一种方法
    /*xEle.ChildNodes[0].InnerXml = FirstName.Text + "Replace";
    xEle.ChildNodes[1].InnerXml = LastName.Text + "Replace";
  xEle.NextSibling.InnerXml = FirstName.Text + "and" + LastName.Text + "Replace";*/

//也可以这样
//true表示递归地克隆指定节点下的子树
    XmlElement xNodeCopy = (XmlElement)xEle.CloneNode(true);//
    xNodeCopy.ChildNodes[0].InnerXml = FirstName.Text + "Replace";
    xNodeCopy.ChildNodes[1].InnerXml = LastName.Text + "Replace";
//xNodeCopy.NextSibling.InnerXml = FirstName.Text + "and" + LastName.Text + "Replace";
    //xNodeCopy.ParentNode.ReplaceChild(xNodeCopy,xEle);  //这样是错误的,因为xNodeCopy只是clone了这个点及子点,并没有父点
   xEle.ParentNode.ReplaceChild(xNodeCopy,xEle);
}
            xDoc.Save(str);

        }


3.3 删除

string str;
str = Server.MapPath("contact.xml");
XmlDocument xDoc = new XmlDocument();
xDoc.Load(str);
XmlElement xEle = null;
//查找是否有存在指定的点
xEle = (XmlElement)xDoc.SelectSingleNode(string.Format("//Name[First='{0}' and Last='{1}']",FirstName.Text,LastName.Text));

if (xEle!=null)  //存在
{
  xEle.ParentNode.ParentNode.RemoveChild(xEle.ParentNode);
    Label6.Text = "delete sucess";
}
else
{
      Label6.Text = "no find";
    }
xDoc.Save(str);

3.4 复制到另一xml

string strSrc,strDst;
strSrc = Server.MapPath("contact.xml"); //源文件
strDst = Server.MapPath("Dst.xml");    //目标文件
XmlDocument xSrcDoc = new XmlDocument();
xSrcDoc.Load(strSrc);
XmlDocument xDstDoc = new XmlDocument();
xDstDoc.Load(strDst);
XmlNodeList xList = null;
XmlNode xDstNode = null;
//假定目标xml中已经存在ContactDetails元素
xDstNode = xDstDoc.SelectSingleNode("//ContactDetails");
xList = xSrcDoc.SelectNodes("//Contact");  //选择所有的点
if (xList!=null&&xDstNode!=null)
{
foreach (XmlNode xNode in xList)
{
     XmlNode xNodeImp = xDstDoc.ImportNode(xNode,true);  //不同xml的 node需导入后才可以在自己的xml 中用
xDstNode.AppendChild(xNodeImp);
     }
}

xDstDoc.Save(strDst);

3.5 除全部

string strDst;
strDst = Server.MapPath("Dst.xml");
XmlDocument xSrcDoc = new XmlDocument();
xSrcDoc.Load(strDst);
//xSrcDoc.DocumentElement.FirstChild.RemoveAll();  //还剩下头节点
xSrcDoc.DocumentElement.RemoveAll();  //删除全部节点
xSrcDoc.Save(strDst);


四.补充

由PrependChild, AppendChild,ReplaceChild, RemoveChild, AppendChild函数可知道,他们的操作都是  父元素.成员函数(操作),所以一般要先找到父元素,Node.ParentNode可以找到
仔细看看用到的类,很多都是直接或间接从XmlNode派生的

五.Xpath语法

5.1 比较常见的
5.1.1 选择所有的该类元素
//Name
contact.xml中所有的Name元素

5.1.2 有条件的选择元素

//Name[FirstName='flypig' and LastName='luo']
contact.xml中FirstName='flypig' 并且 LastName='luo'的Name元素

5.1.3 选择包含有某属性的元素

//cd[@country]

选择所有含有country这个属性的cd元素.

5.1.4 选择包含有属性的元素

//cd[@*]  

选择出含有属性的所有cd元素

5.1.5 选择属性值为**的元素

//cd[@country='UK']

选择出country属性值为UK的cd元素

5.2 以下是我从网上摘抄下来的。

5.2.1 文档一

XPath 是XML的查询语言,和SQL的角色很类似。以下面XML为例,介绍XPath 的语法。
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
  <cd country="USA">
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <price>10.90</price>
  </cd>
  <cd country="UK">
    <title>Hide your heart</title>
    <artist>Bonnie Tyler</artist>
    <price>9.90</price>
  </cd>
  <cd country="USA">
    <title>Greatest Hits</title>
    <artist>Dolly Parton</artist>
    <price>9.90</price>
  </cd>
</catalog>

定位节点

XML是树状结构,类似档案系统内资料夹的结构,XPath也类似档案系统的路径命名方式。不过XPath 是一种模式(Pattern),可以选出 XML档案中,路径符合某个模式的所有节点出来。例如要选catalog底下的cd中所有price元素可以用:
/catalog/cd/price
如果XPath的开头是一个斜线(/)代表这是绝对路径。如果开头是两个斜线(//)表示文件中所有符合模式的元素都会被选出来,即使是处于树中不同的层级也会被选出来。以下的语法会选出文件中所有叫做cd的元素(在树中的任何层级都会被选出来):
//cd
选择未知的元素
使用星号(Wildcards,*)可以选择未知的元素。下面这个语法会选出/catalog/cd 的所有子元素:

/catalog/cd/*
以下的语法会选出所有catalog的子元素中,包含有price作为子元素的元素。
/catalog/*/price
以下的语法会选出有两层父节点,叫做price的所有元素。
/*/*/price
以下的语法会选择出文件中的所有元素。
//*

要注意的是,想要存取不分层级的元素,XPath语法必须以两个斜线开头(//),想要存取未知元素才用星号(*),星号只能代表未知名称的元素,不能代表未知层级的元素。

选择分支
使用中括号可以选择分支。以下的语法从catalog的子元素中取出第一个叫做cd的元素。XPath的定义中没有第0元素这种东西。

/catalog/cd[1]

以下语法选择catalog中的最后一个cd元素:(XPathj并没有定义 first() 这种函式喔,用上例的 [1]就可以取出第一个元素。

/catalog/cd[last()]

以下语法选出含有price子元素的所有/catalog/cd元素。

/catalog/cd[price]

以下语法选出price元素的值等于10.90的所有/catalog/cd元素

/catalog/cd[price=10.90]

以下语法选出price元素的值等于10.90的所有/catalog/cd元素的price元素

/catalog/cd[price=10.90]/price

选择一个以上的路径
使用Or操作数(|)就可以选择一个以上的路径。例如:

/catalog/cd/title | catalog/cd/artist

选择所有title以及artist元素

//title | //artist

选择所有title以及artist以及price元素

//title | //artist | //price

选择属性

在XPath中,除了选择元素以外,也可以选择属性。属性都是以@开头。例如选择文件中所有叫做country的属性:

//@country

选择所有含有country这个属性的cd元素:

//cd[@country]

以下语法选择出含有属性的所有cd元素

//cd[@*]  

以下语法选择出country属性值为UK的cd元素

//cd[@country='UK']

5.2.2 文档二
关于XPath

节点匹配路径Xpath

在利用XSL进行转换的过程中,匹配的概念非常重要。在模板声明语句xsl:template match = ""和模板应用语句xsl:apply-templates select = ""中,用引号括起来的部分必须能够精确地定位节点。具体的定位方法则在XPath中给出。

另外,也可以使用Xpath对XML文档进行搜索、定位。

之所以要引入XPath的概念,目的就是为了在匹配XML文档结构树时能够准确地找到某一个节点元素。可以把XPath比作文件管理路径:通过文件管理路径,可以按照一定的规则查找到所需要的文件;同样,依据XPath所制定的规则,也可以很方便地找到XML结构文档树中的任何一个节点。

在介绍XPath的匹配规则之前,我们先来看一些有关XPath的基本概念。首先要说的是XPath数据类型。XPath可分为四种数据类型:

节点集(node-set)
节点集是通过路径匹配返回的符合条件的一组节点的集合。其它类型的数据不能转换为节点集。

布尔值(boolean)
由函数或布尔表达式返回的条件匹配值,与一般语言中的布尔值相同,有true和false两个值。布尔值可以和数值类型、字符串类型相互转换。

字符串(string)
字符串即包含一系列字符的集合,XPath中提供了一系列的字符串函数。字符串可与数值类型、布尔值类型的数据相互转换。

数值(number)
在XPath中数值为浮点数,可以是双精度64位浮点数。另外包括一些数值的特殊描述,如非数值NaN(Not-a-Number)、正无穷大infinity、负无穷大-infinity、正负0等等。number的整数值可以通过函数取得,另外,数值也可以和布尔类型、字符串类型相互转换。

其中后三种数据类型与其它编程语言中相应的数据类型差不多,只是第一种数据类型是XML文档树的特有产物。另外,由于XPath包含的是对文档结构树的一系列操作,因此搞清楚XPath节点类型也是很必要的。由于XML文档的逻辑结构,一个XML文件可以包含元素、CDATA、注释、处理指令等逻辑要素,其中元素还可以包含属性,并可以利用属性来定义命名空间。相应地,在XPath中,将节点划分为七种节点类型:

根节点(Root Node)
根节点是一棵树的最上层,根节点是唯一的。树上其它所有元素节点都是它的子节点或后代节点。对根节点的处理机制与其它节点相同。在XSLT中对树的匹配总是先从根节点开始。

元素节点(Element Nodes)
元素节点对应于文档中的每一个元素,一个元素节点的子节点可以是元素节点、注释节点、处理指令节点和文本节点。可以为元素节点定义一个唯一的标识id。
元素节点都可以有扩展名,它是由两部分组成的:一部分是命名空间URI,另一部分是本地的命名。

文本节点(Text Nodes)
文本节点包含了一组字符数据,即CDATA中包含的字符。任何一个文本节点都不会有紧邻的兄弟文本节点,而且文本节点没有扩展名。

属性节点(Attribute Nodes)
每一个元素节点有一个相关联的属性节点集合,元素是每个属性节点的父节点,但属性节点却不是其父元素的子节点。这就是说,通过查找元素的子节点可以匹配出元素的属性节点,但反过来不成立,只是单向的。再有,元素的属性节点没有共享性,也就是说不同的元素节点不共有同一个属性节点。
对缺省属性的处理等同于定义了的属性。如果一个属性是在DTD声明的,但声明为#IMPLIED,而该属性没有在元素中定义,则该元素的属性节点集中不包含该属性。
此外,与属性相对应的属性节点都没有命名空间的声明。命名空间属性对应着另一种类型的节点。

命名空间节点(Namespace Nodes)
每一个元素节点都有一个相关的命名空间节点集。在XML文档中,命名空间是通过保留属性声明的,因此,在XPath中,该类节点与属性节点极为相似,它们与父元素之间的关系是单向的,并且不具有共享性。

处理指令节点(Processing Instruction Nodes)
处理指令节点对应于XML文档中的每一条处理指令。它也有扩展名,扩展名的本地命名指向处理对象,而命名空间部分为空。

注释节点(Comment Nodes)
注释节点对应于文档中的注释。下面,我们来构造一棵XML文档树:

现在,来实现一些利用Xpath使XML中节点匹配的基本方法。

路径匹配
路径匹配与文件路径的表示相仿,比较好理解。有以下几个符号:

符 号

 含 义

 举 例

 匹配结果 
/

 指示节点路径

 /A/C/D
 节点"A"的子节点"C"的子节点"D",即id值为d2的D节点
/
 根节点
//
 所有路径以"//"后指定的子路径结尾的元素

 //E
 所有E元素,结果是所有三个E元素
 
//C/E
 所有父节点为C的E元素,结果是id值为e1和e2的两个E元素

*
 路径的通配符

 /A/B/C/*
 A元素→B元素→C元素下的所有子元素,即name值为b的B元素、id值为d1的D元素和id值为e1和e2的两个E元素

/*/*/D
 上面有两级节点的D元素,匹配结果是id值为d2的D元素

//*
 所有的元素

|
 逻辑或

 //B | //C
所有B元素和C元素

位置匹配
对于每一个元素,它的各个子元素是有序的。如:

举 例

 含 义
 匹配结果 
/A/B/C[1]
 A元素→B元素→C元素的第一个子元素

 name值为b的B元素
 
/A/B/C[last()]

 A元素→B元素→C元素的最后一个子元素
 id值为e2的E元素
 
/A/B/C[position()>1]
 A元素→B元素→C元素之下的位置号大于1的元素

 id值为d1的D元素和两个具有id值的E元素

属性及属性值
在XPath中可以利用属性及属性值来匹配元素,要注意的是,元素的属性名前要有"@"前缀。例如:

举 例
 含 义
 匹配结果
//B[@id]
 所有具有属性id的B元素
 id值为b1和b2的两个B元素

//B[@*]
 所有具有属性的B元素
 两个具有id属性的B元素和一个具有name属性B元素
 
//B[not(@*)]
 所有不具有属性的B元素
 A元素→C元素下的B元素

//B[@id="b1"]
 id值为b1的B元素
 A元素下的B元素

亲属关系匹配
XML文档可归结为树型结构,因此任何一个节点都不是孤立的。通常我们把节点之间的归属关系归结为一种亲属关系,如父亲、孩子、祖先、后代、兄弟等等。在对元素进行匹配时,同样可以用到这些概念。例如:

举 例
 含 义
 匹配结果
//E/parent::*
 所有E节点的父节点元素
 id值为a1的A元素和id值为c1的C元素
//F/ancestor::*
 所有F元素的祖先节点元素
 id值为a1的A元素和id值为c2的C元素

/A/child::*
 A的子元素
 id值为b1、b2的B元素,id值为c2的C元素,以及没有任何属性的E元素
 
/A/descendant::*
 A的所有后代元素
 除A元素以外的所有其它元素
 
//F/self::*
 所有F的自身元素
 F元素本身

//F/ancestor-or-self::*
 所有F元素及它的祖先节点元素
 F元素、F元素的父节点C元素和A元素
 
/A/C/descendant-or-self::*
 所有A元素→C元素及它们的后代元素
 id值为c2的C元素、该元素的子元素B、D、F元素
 
/A/C/following-sibling::*
 A元素→C元素的紧邻的后序所有兄弟节点元素
 没有任何属性的E元素
 
/A/C/preceding-sibling::*
 A元素→C元素的紧邻的前面所有兄弟节点元素
 id值为b1和b2的两个B元素

/A/B/C/following::*
 A元素→B元素→C元素的后序的所有元素
 id为b2的B元素、无属性的C元素、无属性的B元素、id为d2的D元素、无属性的F元素、无属性的E元素。

/A/C/preceding::*
 A元素→C元素的前面的所有元素
 id为b2的B元素、id为e2的E元素、id为e1的E元素、id为d1的D元素、name为b的B元素、id为c1的C元素、id为b1的B元素

条件匹配
条件匹配就是利用一些函数的运算结果的布尔值来匹配符合条件的节点。常用于条件匹配的函数有四大类:节点函数、字符串函数、数值函数、布尔函数。例如前面提到的last()、position()等等。这些功能函数可以帮助我们精确寻找需要的节点。

函数及功能

 作用 
count()功能
 统计计数,返回符合条件的节点的个数
 
number()功能
 将属性的值中的文本转换为数值
 
substring() 功能
语法:substring(value, start, length)

 截取字符串
 
sum()功能
 求和
这些功能只是XPath语法中的一部分,还有大量的功能函数没有介绍,而且目前XPath的语法仍然在不断发展中。通过这些函数我们可以实现更加复杂的查询和操作。
以上这些匹配方法中,用得最多的还要数路径匹配。依靠给出相对于当前路径的子路径来定位节点的

posted @ 2006-11-28 22:41 春夏秋冬 阅读(87) | 评论 (0)编辑