<?xml version="1.0" encoding="GBK" ?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dcterms="http://purl.org/dc/terms/">
 <channel>
  	  <title><![CDATA[黑海的博客]]></title>
	  <link>http://robinpcy.blog.163.com</link>
	  <description><![CDATA[在这里我为灾区的同胞们祈福！！！ ]]></description>
	  <language>zh-CN</language>
	  <pubDate>Fri, 25 Jul 2008 20:44:01 +0800</pubDate>
	  <lastBuildDate>Fri, 25 Jul 2008 20:44:01 +0800</lastBuildDate>
	  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
	  <generator><![CDATA[NetEase Space]]></generator>
	  <managingEditor><![CDATA[robinpcy]]></managingEditor>
	  <webMaster><![CDATA[黑海]]></webMaster>
		  <ttl>120</ttl>
	  <image>
	  	<title><![CDATA[黑海的博客]]></title>
	  	<url>http://ava.blog.163.com/photo/heN6Rln-2V07N7XCgMFS8g==/4507258802067852741.jpg</url>
	  	<link>http://robinpcy.blog.163.com</link>
	  </image>
  <item>
  	<title><![CDATA[ASP获取当前网址(IE里面的网址)]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/37475972200862584125259</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">ASP获取当前网址</P>
<P style="TEXT-INDENT: 2em">&lt;%</P>
<P style="TEXT-INDENT: 2em">Function GetUrl() </P>
<P style="TEXT-INDENT: 2em">Dim strHostName,strScriptName,strSubUrl,strRequestItem </P>
<P style="TEXT-INDENT: 2em">strHostName=CStr(Request.ServerVariables("LOCAL_ADDR"))</P>
<P style="TEXT-INDENT: 2em">strScriptName=CStr(Request.ServerVariables("SCRIPT_NAME"))</P>
<P style="TEXT-INDENT: 2em">strSubUrl=""</P>
<P style="TEXT-INDENT: 2em">If Request.QueryString&lt;&gt;"" Then</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; strScriptName=strScriptName&amp;"?"</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; For Each strRequestItem In Request.QueryString</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; If InStr(strScriptName,strRequestItem)=0 Then</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; If strSubUrl="" Then</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strSubUrl=strSubUrl&amp;strRequestItem&amp;"="&amp;Server.URLEncode(Request.QueryString(""&amp;strRequestItem&amp;""))</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; Else</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strSubUrl=strSubUrl&amp;"&amp;"&amp;strRequestItem&amp;"="&amp;Server.URLEncode(Request.QueryString(""&amp;strRequestItem&amp;""))</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; End If</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; End If</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; Next</P>
<P style="TEXT-INDENT: 2em">End If</P>
<P style="TEXT-INDENT: 2em">GetUrl="http://"&amp;strHostName&amp;strScriptName&amp;strSubUrl</P>
<P style="TEXT-INDENT: 2em">End Function</P>
<P style="TEXT-INDENT: 2em">%&gt;</P>
<P style="TEXT-INDENT: 2em">或者用这个</P>
<P style="TEXT-INDENT: 2em">GetUrl ="http://"&amp;Request.ServerVariables("SERVER_NAME") &amp; Request.ServerVariables("URL")</P>
<P style="TEXT-INDENT: 2em">获取网址</P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/37475972200862584125259</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/37475972200862584125259</guid>
    <pubDate>Fri, 25 Jul 2008 20:41:25 +0800</pubDate>
    <dcterms:modified>2008-07-25T20:41:25+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[如何在asp中获取当前网页的&quot;标题&quot;(title)和&quot;网址&quot;(url)]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/37475972200862583824384</link>
    <description><![CDATA[<div><DIV>
<P style="TEXT-INDENT: 2em">&lt;%</P>
<P style="TEXT-INDENT: 2em">Function getHTTPPage(url) </P>
<P style="TEXT-INDENT: 2em">on error resume next </P>
<P style="TEXT-INDENT: 2em">dim http </P>
<P style="TEXT-INDENT: 2em">set http=Server.createobject("Msxml2.XMLHTTP") </P>
<P style="TEXT-INDENT: 2em">Http.open "GET",url,false </P>
<P style="TEXT-INDENT: 2em">Http.send() </P>
<P style="TEXT-INDENT: 2em">if Http.readystate&lt;&gt;4 then</P>
<P style="TEXT-INDENT: 2em">exit function </P>
<P style="TEXT-INDENT: 2em">end if</P>
<P style="TEXT-INDENT: 2em">getHTTPPage=bytes2BSTR(Http.responseBody) </P>
<P style="TEXT-INDENT: 2em">set http=nothing</P>
<P style="TEXT-INDENT: 2em">if err.number&lt;&gt;0 then</P>
<P style="TEXT-INDENT: 2em">err.Clear </P>
<P style="TEXT-INDENT: 2em">end if </P>
<P style="TEXT-INDENT: 2em">End Function </P>
<P style="TEXT-INDENT: 2em">Function bytes2BSTR(vIn) </P>
<P style="TEXT-INDENT: 2em">dim strReturn </P>
<P style="TEXT-INDENT: 2em">dim i,ThisCharCode,NextCharCode </P>
<P style="TEXT-INDENT: 2em">strReturn = "" </P>
<P style="TEXT-INDENT: 2em">For i = 1 To LenB(vIn) </P>
<P style="TEXT-INDENT: 2em">ThisCharCode = AscB(MidB(vIn,i,1)) </P>
<P style="TEXT-INDENT: 2em">If ThisCharCode &lt; &amp;H80 Then </P>
<P style="TEXT-INDENT: 2em">strReturn = strReturn &amp; Chr(ThisCharCode) </P>
<P style="TEXT-INDENT: 2em">Else </P>
<P style="TEXT-INDENT: 2em">NextCharCode = AscB(MidB(vIn,i+1,1)) </P>
<P style="TEXT-INDENT: 2em">strReturn = strReturn &amp; Chr(CLng(ThisCharCode) * &amp;H100 + CInt(NextCharCode)) </P>
<P style="TEXT-INDENT: 2em">i = i + 1 </P>
<P style="TEXT-INDENT: 2em">End If </P>
<P style="TEXT-INDENT: 2em">Next </P>
<P style="TEXT-INDENT: 2em">bytes2BSTR = strReturn </P>
<P style="TEXT-INDENT: 2em">End Function</P>
<P style="TEXT-INDENT: 2em">Function GetPageTitle(HtmlContent)</P>
<P style="TEXT-INDENT: 2em">Dim l,j,strTitle</P>
<P style="TEXT-INDENT: 2em">l = InStr(LCase(HtmlContent), "&lt;title&gt;")</P>
<P style="TEXT-INDENT: 2em">If l &gt; 0 Then</P>
<P style="TEXT-INDENT: 2em">l = l + 7</P>
<P style="TEXT-INDENT: 2em">j = InStr(l, LCase(HtmlContent), "&lt;/title&gt;")</P>
<P style="TEXT-INDENT: 2em">If j &gt; 0 Then</P>
<P style="TEXT-INDENT: 2em">strTemp = Mid(HtmlContent, l, j - l) </P>
<P style="TEXT-INDENT: 2em">Else</P>
<P style="TEXT-INDENT: 2em">strTemp = "无法获取网页标题!"</P>
<P style="TEXT-INDENT: 2em">End If</P>
<P style="TEXT-INDENT: 2em">Else</P>
<P style="TEXT-INDENT: 2em">strTemp = "无法获取网页标题!"</P>
<P style="TEXT-INDENT: 2em">End If</P>
<P style="TEXT-INDENT: 2em">GetPageTitle = strTemp </P>
<P style="TEXT-INDENT: 2em">End Function</P>
<P style="TEXT-INDENT: 2em">HtmlCldeContent = getHTTPPage("http://www.aaaa.com/bbs/") '要提取页面的url地址</P>
<P style="TEXT-INDENT: 2em">Title = GetPageTitle(HtmlCldeContent)</P>
<P style="TEXT-INDENT: 2em">response.write(Title)</P>
<P style="TEXT-INDENT: 2em">%&gt;</EMBED></P></DIV></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/37475972200862583824384</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/37475972200862583824384</guid>
    <pubDate>Fri, 25 Jul 2008 20:38:24 +0800</pubDate>
    <dcterms:modified>2008-07-25T20:38:24+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[ASP导出EXCEL文档]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/3747597220084995327755</link>
    <description><![CDATA[<div><P>&lt;%<BR>server.scripttimeout=100000&nbsp;&nbsp; '处理时间较长，设置值应大一点<BR>On Error Resume Next <BR>set objExcelApp = server.CreateObject("Excel.Application")<BR>objExcelApp.DisplayAlerts = false<BR>objExcelApp.Application.Visible = false<BR>objExcelApp.WorkBooks.add<BR>set objExcelBook = objExcelApp.ActiveWorkBook<BR>set objExcelSheets = objExcelBook.Worksheets<BR>set objSpreadsheet = objExcelBook.Sheets(1)<BR>Dim Conn<BR>Dim Connstr<BR>Dim DB<BR>DB="db/db.mdb"<BR>Set conn = Server.CreateObject("ADODB.Connection")<BR>Connstr="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &amp; Server.MapPath(DB)<BR>Conn.Open Connstr<BR>Dim objRS<BR>Set objRS = Server.CreateObject("ADODB.Recordset") <BR>objRS.Open "SELECT * FROM table1",conn,1,3<BR>If objRS.EOF then <BR>&nbsp;response.write("Error") <BR>&nbsp;respose.end<BR>End if<BR>Dim objField, iCol, iRow <BR>iCol = 1&nbsp; '取得列号<BR>iRow = 1 '取得行号<BR>objSpreadsheet.Cells(iRow, iCol).Value = "吉盟首饰"&nbsp; '单元格插入数据<BR>objSpreadsheet.Columns(iCol).ShrinkToFit=true&nbsp; '设定是否自动适应表格单元大小(单元格宽不变）<BR>'设置Excel表里的字体 <BR>objSpreadsheet.Cells(iRow, iCol).Font.Bold = True&nbsp; '单元格字体加粗<BR>objSpreadsheet.Cells(iRow, iCol).Font.Italic = False&nbsp; '单元格字体倾斜<BR>objSpreadsheet.Cells(iRow, iCol).Font.Size = 30&nbsp; '设置单元格字号<BR>objSpreadsheet.Cells(iRow, iCol).ParagraphFormat.Alignment=1 '设置单元格对齐格式:居中<BR>objspreadsheet.Cells(iRow,iCol).font.name="隶书" '设置单元格字体<BR>objspreadsheet.Cells(iRow,iCol).font.ColorIndex=5 '设置单元格文字的颜色<BR>objSpreadsheet.Range("A1:F1").merge&nbsp;&nbsp; '合并单元格(单元区域)<BR>objSpreadsheet.Range("A1:F1").Interior.ColorIndex = 2&nbsp; '设计单元络背景色<BR>'objSpreadsheet.Range("A2:F2").WrapText=true '设置字符回卷（自动换行）<BR>iRow=iRow+1<BR>For Each objField in objRS.Fields <BR>'objSpreadsheet.Columns(iCol).ShrinkToFit=true<BR>objSpreadsheet.Cells(iRow, iCol).Value = objField.Name<BR>'设置Excel表里的字体 <BR>objSpreadsheet.Cells(iRow, iCol).Font.Bold = True <BR>objspreadsheet.Cells(iRow, iCol).Font.name="宋体"<BR>objSpreadsheet.Cells(iRow, iCol).Font.Italic = False <BR>objSpreadsheet.Cells(iRow, iCol).Font.Size = 12<BR>objSpreadsheet.Cells(iRow, iCol).Halignment = 2 '居中 <BR>iCol = iCol + 1 <BR>Next 'objField <BR>'Display all of the data <BR>Do While Not objRS.EOF <BR>iRow = iRow + 1 <BR>iCol = 1 <BR>For Each objField in objRS.Fields <BR>If IsNull(objField.Value) then <BR>objSpreadsheet.Cells(iRow, iCol).Value = "" <BR>Else <BR>objSpreadsheet.Columns(iCol).ShrinkToFit=true <BR>objSpreadsheet.Cells(iRow, iCol).Value = objField.Value <BR>objSpreadsheet.Cells(iRow, iCol).Halignment = 2<BR>objSpreadsheet.Cells(iRow, iCol).Font.Bold = False <BR>objSpreadsheet.Cells(iRow, iCol).Font.Italic = False <BR>objSpreadsheet.Cells(iRow, iCol).Font.Size = 10 <BR>'objSpreadsheet.Cells(iRow, iCol).Halignment = 2<BR>objSpreadsheet.Cells(iRow, iCol).ParagraphFormat.Alignment=1<BR>End If <BR>iCol = iCol + 1 <BR>Next&nbsp;&nbsp;&nbsp; 'objField <BR>objRS.MoveNext <BR>Loop <BR>Dim SaveName <BR>SaveName="temp1"<BR>Dim objExcel <BR>Dim ExcelPath <BR>ExcelPath = "MakeExcel/" &amp; SaveName &amp; ".xls" <BR>objExcelBook.SaveAs server.mappath(ExcelPath)<BR>response.write("&lt;a href='" &amp; server.URLEncode(ExcelPath) &amp; "'&gt;下载&lt;/a&gt;") <BR>objExcelApp.Quit<BR>set objExcelApp = Nothing<BR>%&gt; </P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/3747597220084995327755</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/3747597220084995327755</guid>
    <pubDate>Fri, 9 May 2008 21:53:27 +0800</pubDate>
    <dcterms:modified>2008-05-09T21:53:27+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[AJAX基础教程]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/3747597220084995022781</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">这篇文章将带您浏览整个AJAX的基本概貌,并展示两个简单的例子让您轻松上路. </P>
<P style="TEXT-INDENT: 2em">　　什么是 AJAX? </P>
<P style="TEXT-INDENT: 2em">　　AJAX (异步 JavaScript 和 XML) 是个新产生的术语,专为描述JavaScript的两项强大性能.这两项性能在多年来一直被网络开发者所忽略,直到最近Gmail, Google suggest和google Maps的横空出世才使人们开始意识到其重要性. </P>
<P style="TEXT-INDENT: 2em">　　这两项被忽视的性能是: </P>
<P style="TEXT-INDENT: 2em">　　无需重新装载整个页面便能向服务器发送请求. </P>
<P style="TEXT-INDENT: 2em">　　对XML文档的解析和处理． </P>
<P style="TEXT-INDENT: 2em">步骤 1 – "请!" --- 如何发送一个HTTP请求 </P>
<P style="TEXT-INDENT: 2em">　　为了用JavaScript向服务器发送一个HTTP请求, 需要一个具备这种功能的类实例. 这样的类首先由Internet Explorer以ActiveX对象引入, 被称为XMLHTTP. 后来Mozilla, Safari 和其他浏览器纷纷仿效, 提供了XMLHttpRequest类,它支持微软的ActiveX对象所提供的方法和属性. </P>
<P style="TEXT-INDENT: 2em">　　因此, 为了创建一个跨浏览器的这样的类实例(对象), 可以应用如下代码: </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">if (window.XMLHttpRequest) { // Mozilla, Safari, ... http_request = new XMLHttpRequest(); } else if (window.ActiveXObject) { // IE http_request = new ActiveXObject("Microsoft.XMLHTTP"); } </P>
<P style="TEXT-INDENT: 2em">　　(上例对代码做了一定简化,这是为了解释如何创建XMLHTTP类实例. 实际的代码实例可参阅本篇步骤3.) </P>
<P style="TEXT-INDENT: 2em">　　如果服务器的响应没有XML mime-type header,某些Mozilla浏览器可能无法正常工作. 为了解决这个问题, 如果服务器响应的header不是text/xml,可以调用其它方法修改该header. </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">http_request = new XMLHttpRequest(); http_request.overrideMimeType('text/xml'); </P>
<P style="TEXT-INDENT: 2em">　　接下来要决定当收到服务器的响应后,需要做什么.这需要告诉HTTP请求对象用哪一个JavaScript函数处理这个响应.可以将对象的onreadystatechange属性设置为要使用的JavaScript的函数名,如下所示: </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">http_request.onreadystatechange = nameOfTheFunction; </P>
<P style="TEXT-INDENT: 2em">　　注意:在函数名后没有括号,也无需传递参数.另外还有一种方法,可以在扉页(fly)中定义函数及其对响应要采取的行为,如下所示: </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">http_request.onreadystatechange = function(){ // do the thing }; </P>
<P style="TEXT-INDENT: 2em">　　在定义了如何处理响应后,就要发送请求了.可以调用HTTP请求类的open()和send()方法, 如下所示: </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">http_request.open('GET', 'http://www.example.org/some.file', true); http_request.send(null); </P>
<P style="TEXT-INDENT: 2em">　　open()的第一个参数是HTTP请求方式 – GET, POST, HEAD 或任何服务器所支持的您想调用的方式. 按照HTTP规范,该参数要大写;否则,某些浏览器(如Firefox)可能无法处理请求.有关HTTP请求方法的详细信息可参考http: //www.w3.org/Protocols/rfc2616/rfc2616-sec9.html W3C specs </P>
<P style="TEXT-INDENT: 2em">　　第二个参数是请求页面的URL.由于自身安全特性的限制,该页面不能为第三方域名的页面.同时一定要保证在所有的页面中都使用准确的域名,否则调用 open()会得到 "permission denied"的错误提示.一个常见的错误是访问站点时使用domain.tld,而当请求页面时,却使用www.domain.tld. </P>
<P style="TEXT-INDENT: 2em">　　第三个参数设置请求是否为异步模式.如果是TRUE, JavaScript函数将继续执行,而不等待服务器响应.这就是"AJAX"中的"A". </P>
<P style="TEXT-INDENT: 2em">　　如果第一个参数是"POST",send()方法的参数可以是任何想送给服务器的数据. 这时数据要以字符串的形式送给服务器,如下所示: </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">name=value&amp;anothername=othervalue&amp;so=on </P>
<P style="TEXT-INDENT: 2em">步骤 2 – "收到!" --- 处理服务器的响应 </P>
<P style="TEXT-INDENT: 2em">　　当发送请求时,要提供指定处理响应的JavaScript函数名. </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">http_request.onreadystatechange = nameOfTheFunction; </P>
<P style="TEXT-INDENT: 2em">　　我们来看看这个函数的功能是什么.首先函数会检查请求的状态.如果状态值是4,就意味着一个完整的服务器响应已经收到了,您将可以处理该响应. </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">if (http_request.readyState == 4) { // everything is good, the response is received } else { // still not ready } </P>
<P style="TEXT-INDENT: 2em">　　readyState的取值如下: </P>
<P style="TEXT-INDENT: 2em">　　0 (未初始化) </P>
<P style="TEXT-INDENT: 2em">　　1 (正在装载) </P>
<P style="TEXT-INDENT: 2em">　　2 (装载完毕) </P>
<P style="TEXT-INDENT: 2em">　　3 (交互中) </P>
<P style="TEXT-INDENT: 2em">　　4 (完成) </P>
<P style="TEXT-INDENT: 2em">　　接着,函数会检查HTTP服务器响应的状态值. 完整的状态取值可参见 W3C site. 我们着重看值为200 OK的响应. </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">if (http_request.status == 200) { // perfect! } else { // there was a problem with the request, // for example the response may be a 404 (Not Found) // or 500 (Internal Server Error) response codes } </P>
<P style="TEXT-INDENT: 2em">　　在检查完请求的状态值和响应的HTTP状态值后, 您就可以处理从服务器得到的数据了.有两种方式可以得到这些数据: </P>
<P style="TEXT-INDENT: 2em">http_request.responseText – 以文本字符串的方式返回服务器的响应 </P>
<P style="TEXT-INDENT: 2em">http_request.responseXML – 以XMLDocument对象方式返回响应.处理XMLDocument对象可以用JavaScript DOM函数 </P>
<P style="TEXT-INDENT: 2em">步骤 3 – "万事俱备!" - 简单实例 </P>
<P style="TEXT-INDENT: 2em">　　我们现在将整个过程完整地做一次,发送一个简单的HTTP请求. 我们用JavaScript请求一个HTML文件, test.html, 文件的文本内容为"I'm a test.".然后我们"alert()"test.html文件的内容. </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">&lt;script type="text/javascript" language="javascript"&gt; var http_request = false; function makeRequest(url) { http_request = false; if (window.XMLHttpRequest) { // Mozilla, Safari,... http_request = new XMLHttpRequest(); if (http_request.overrideMimeType) { http_request.overrideMimeType('text/xml'); } } else if (window.ActiveXObject) { // IE try { http_request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { http_request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {} } } if (!http_request) { alert('Giving up :( Cannot create an XMLHTTP instance'); return false; } http_request.onreadystatechange = alertContents; http_request.open('GET', url, true); http_request.send(null); } function alertContents() { if (http_request.readyState == 4) { if (http_request.status == 200) { alert(http_request.responseText); } else { alert('There was a problem with the request.'); } } } &lt;/script&gt; &lt;span style="cursor: pointer; text-decoration: underline" onclick="makeRequest('test.html')"&gt; Make a request &lt;/span&gt; </P>
<P style="TEXT-INDENT: 2em">　　本例中: </P>
<P style="TEXT-INDENT: 2em">　　用户点击浏览器上的"请求"链接; </P>
<P style="TEXT-INDENT: 2em">　　接着函数makeRequest()将被调用.其参数 – HTML文件test.html在同一目录下; </P>
<P style="TEXT-INDENT: 2em">　　这样就发起了一个请求.onreadystatechange的执行结果会被传送给alertContents(); </P>
<P style="TEXT-INDENT: 2em">　　alertContents()将检查服务器的响应是否成功地收到,如果是,就会"alert()"test.html文件的内容. </P>
<P style="TEXT-INDENT: 2em">步骤 4 – "X-文档" --- 处理XML响应 </P>
<P style="TEXT-INDENT: 2em">　　在前面的例子中,当服务器对HTTP请求的响应被收到后,我们会调用请求对象的reponseText属性.该属性包含了test.html文件的内容.现在我们来试试responseXML属性. </P>
<P style="TEXT-INDENT: 2em">　　首先,我们新建一个有效的XML文件,后面我们将使用这个文件.该文件(test.xml)源代码如下所示: </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">&lt;?xml version="1.0" ?&gt; &lt;root&gt; I'm a test. &lt;/root&gt; </P>
<P style="TEXT-INDENT: 2em">　　在该脚本中,我们只需修改请求部分: </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">... onclick="makeRequest('test.xml')"&gt; ... </P>
<P style="TEXT-INDENT: 2em">　　接着,在alertContents()中,我们将alert()的代码alert(http_request.responseText);换成: </P>
<P style="TEXT-INDENT: 2em">代码: </P>
<P style="TEXT-INDENT: 2em">　　var xmldoc = http_request.responseXML; 　　var root_node = xmldoc.getElementsByTagName('root').item(0); 　　alert(root_node.firstChild.data); </P>
<P style="TEXT-INDENT: 2em">　　这里,我们使用了responseXML提供的XMLDocument对象并用DOM方法获取存于XML文件中的内容.</P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/3747597220084995022781</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/3747597220084995022781</guid>
    <pubDate>Fri, 9 May 2008 21:50:22 +0800</pubDate>
    <dcterms:modified>2008-05-09T21:50:22+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[各种AJAX控件和类库]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/374759722008499483348</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">Ajax控件和类库现在真的太多了，不知不觉中增加了Ajax的神秘性和复杂性，看到版内很多人为此费解和伤神，决定发此贴谈谈本人对Ajax的观点，希望能让大家对Ajax有一个本质的认识。 </P>
<P style="TEXT-INDENT: 2em">　　观点一：Ajax和<A href="http://www.chinahtml.com/systems/">服务器</A>端技术毫不相关 </P>
<P style="TEXT-INDENT: 2em">　　严格的说，与传统web开发相比，Ajax是完完全全的客户端技术。由于很多控件封装了客户端和<A href="http://www.chinahtml.com/systems/">服务器</A>端的通信过程，因此很多问题也因通信而起。事实上，不论何种Ajax技术，<A href="http://www.chinahtml.com/systems/">服务器</A>端都是返回的一个纯文本流，再由客户端来处理这个文本。这段文本可以是xml格式，也可以是一个Html片段，也可以是一段JavaScript脚本，或者仅是一个字符串。<A href="http://www.chinahtml.com/systems/">服务器</A>端仅仅是作为一个数据接口，客户端使用XMLHttpRequest对象来请求这个页面，<A href="http://www.chinahtml.com/systems/">服务器</A>端在页面内写入结果文本，这个过程和普通的web开发没有任何区别。所不同的只是，客户端在异步获取结果后，不是直接显示在页面，而是由客户端的Javascript脚本处理后再显示在页面。至于各种控件所谓的能返回DataSet对象，Date对象，或者其他的数据类型，都是封装了这个处理过程的结果。 </P>
<P style="TEXT-INDENT: 2em">　　观点二：DOM模型是Ajax最本质的技术 </P>
<P style="TEXT-INDENT: 2em">　　之所以没有把XMLHttpRequest列为最本质的技术，因为本人觉得它实在是太简单了，它只是可以让浏览器在后台请求一个页面，并将其内容交给JavaScript处理。真正的核心应该是：DOM模型，即文档对象模型。在DOM模型里，Html标记都被认为是一个对象，例如：div对象，table对象等等。DOM模型就规定了这些对象所具有的属性、方法和事件。通过这些性质，可以对一个已经显示于浏览器的页面进行内容的修改，例如增加节点、修改节点位置，删除节点等等。而不仅仅是一个innerHTML属性这么简单，虽然这是一个很有用的属性。 </P>
<P style="TEXT-INDENT: 2em">　　观点三：在使用Ajax控件前理解它们的实现 </P>
<P style="TEXT-INDENT: 2em">　　使用Ajax控件的确可以提高效率，但如果你空中楼阁般使用控件，那就得不偿失了。从一个控件换到另外一个控件又会有一个漫长的学习曲线。所以应该从底层了解其，况且Ajax实在不是什么高深的技术。其实任何东西的最底层其实都是简单的，但如果封装了这些底层的东西，事情会变得复杂和难以理解。以Asp.net为例，它的定制特性可以使得只要在方法前加上[ajax method]类似这样的标志就可以称为一个异步方法，相信这使得Asp.net的Ajax开发显得更加“高效”或者是“神秘”，而更多的事情则被封装了。同样记住一条，任何对<A href="http://www.chinahtml.com/systems/">服务器</A>端的请求仅仅是返回纯文本，我们不一定要依赖于封装好的处理过程，而完全可以自己来实现。 </P>
<P style="TEXT-INDENT: 2em">　　观点四：学好JavaScript </P>
<P style="TEXT-INDENT: 2em">　　在大多数人看来，JavaScript总不是那么一种正规的语言，随便copy一段就碰巧能运行，学过c之类的人，一看也能看懂，而且在浏览器中常常有脚本错误提示，所以潜意识觉得总不能付之以大任。事实上，要学好Ajax，这就完全是一种错误的看法。javascript作为一种脚本语言，其语法的确不是很严格，但并不妨碍其完成诸多复杂的任务，没有JavaScript，就没有Ajax。所以本人强烈建议，学Ajax前，一定要好好研究一番JavaScript，一般来讲，如果能顺利看懂prototype框架的代码（如：prototype-1.3.1.js），你的JavaScript水平就基本过关了。同时对DOM模型也可以算有一个基本的了解。 </P>
<P style="TEXT-INDENT: 2em">　　观点五：Ajax点缀：CSS </P>
<P style="TEXT-INDENT: 2em">　　用JavaScript控制CSS其实很简单，基本上每个DOM对象都有一个style对象，只要把css属性里的"-"去掉，并让随后的字母变为大写就可以作为属性使用了，例如：element.style.backgroundColor="#f00";在css是：选择符 {background-color:#f00}</P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/374759722008499483348</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/374759722008499483348</guid>
    <pubDate>Fri, 9 May 2008 21:48:03 +0800</pubDate>
    <dcterms:modified>2008-05-09T21:48:03+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[用XMLHTTP Post/Get HTML页面时的中文乱码之完全Script解决方案]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/3747597220084994453745</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">先看看E文的表单是怎么提交的： </P>
<P style="TEXT-INDENT: 2em">&lt;SCRIPT&nbsp;language="JavaScript"&gt; </P>
<P style="TEXT-INDENT: 2em">strA&nbsp;=&nbsp;"submit1=Submit&amp;text1=scsdfsd"; </P>
<P style="TEXT-INDENT: 2em">var&nbsp;oReq&nbsp;=&nbsp;new&nbsp;ActiveXObject("MSXML2.XMLHTTP"); </P>
<P style="TEXT-INDENT: 2em">oReq.open("POST","http://ServerName/VDir/TstResult.asp",false); </P>
<P style="TEXT-INDENT: 2em">oReq.setRequestHeader("Content-Length",strA.length);&nbsp; </P>
<P style="TEXT-INDENT: 2em">oReq.setRequestHeader("CONTENT-TYPE","application/x-www-form-urlencoded"); </P>
<P style="TEXT-INDENT: 2em">oReq.send(strA); </P>
<P style="TEXT-INDENT: 2em">&lt;/ScRIPT&gt;</P>
<P style="TEXT-INDENT: 2em">如果把strA = "submit1=Submit&amp;text1=scsdfsd";换成：</P>
<P style="TEXT-INDENT: 2em">strA = "submit1=Submit&amp;text1=中文";</P>
<P style="TEXT-INDENT: 2em">你会发现提交上去的东东根本不对，ASP中Request.Form("Text1"）根本取不到值。俺用Request.BinaryRead把一个 HTML Form中的Post内容写出来看了看，才发现问题——Form提交时也要编码的，编码后的中文是类似于%??%??的转义字符，比如“中文”就被编码为：%D6%D0%CE%C4。呵呵，也怪俺笨，人家CONTENT-TYPE里明明写的清清楚楚——application/x-www-form- urlencoded，urlencoded嘛当然就是这个样子了。既然这样,那我们也知道该怎么办了——自己做转换，代码见下：</P>
<P style="TEXT-INDENT: 2em">&lt;SCRIPT&nbsp;language="VBScript"&gt; </P>
<P style="TEXT-INDENT: 2em">Function&nbsp;URLEncoding(vstrIn) </P>
<P style="TEXT-INDENT: 2em">strReturn&nbsp;=&nbsp;"" </P>
<P style="TEXT-INDENT: 2em">For&nbsp;i&nbsp;=&nbsp;1&nbsp;To&nbsp;Len(vstrIn) </P>
<P style="TEXT-INDENT: 2em">ThisChr&nbsp;=&nbsp;Mid(vStrIn,i,1) </P>
<P style="TEXT-INDENT: 2em">If&nbsp;Abs(Asc(ThisChr))&nbsp;&lt;&nbsp;&amp;HFF&nbsp;Then </P>
<P style="TEXT-INDENT: 2em">strReturn&nbsp;=&nbsp;strReturn&nbsp;&amp;&nbsp;ThisChr </P>
<P style="TEXT-INDENT: 2em">Else </P>
<P style="TEXT-INDENT: 2em">innerCode&nbsp;=&nbsp;Asc(ThisChr) </P>
<P style="TEXT-INDENT: 2em">If&nbsp;innerCode&nbsp;&lt;&nbsp;0&nbsp;Then </P>
<P style="TEXT-INDENT: 2em">innerCode&nbsp;=&nbsp;innerCode&nbsp;+&nbsp;&amp;H10000 </P>
<P style="TEXT-INDENT: 2em">End&nbsp;If </P>
<P style="TEXT-INDENT: 2em">Hight8&nbsp;=&nbsp;(innerCode&nbsp;And&nbsp;&amp;HFF00)\&nbsp;&amp;HFF </P>
<P style="TEXT-INDENT: 2em">Low8&nbsp;=&nbsp;innerCode&nbsp;And&nbsp;&amp;HFF </P>
<P style="TEXT-INDENT: 2em">strReturn&nbsp;=&nbsp;strReturn&nbsp;&amp;&nbsp;"%"&nbsp;&amp;&nbsp;Hex(Hight8)&nbsp;&amp;&nbsp;"%"&nbsp;&amp;&nbsp;Hex(Low8) </P>
<P style="TEXT-INDENT: 2em">End&nbsp;If </P>
<P style="TEXT-INDENT: 2em">Next </P>
<P style="TEXT-INDENT: 2em">URLEncoding&nbsp;=&nbsp;strReturn </P>
<P style="TEXT-INDENT: 2em">End&nbsp;Function </P>
<P style="TEXT-INDENT: 2em">strA&nbsp;=&nbsp;URLEncoding("submit1=Submit&amp;text1=中文") </P>
<P style="TEXT-INDENT: 2em">oReq&nbsp;=&nbsp;CreateObject("MSXML2.XMLHTTP") </P>
<P style="TEXT-INDENT: 2em">oReq.open&nbsp;"POST","http://ServerName/VDir/TstResult.asp",false </P>
<P style="TEXT-INDENT: 2em">oReq.setRequestHeader&nbsp;"Content-Length",Len(strA) </P>
<P style="TEXT-INDENT: 2em">oReq.setRequestHeader&nbsp;"CONTENT-TYPE","application/x-www-form-urlencoded" </P>
<P style="TEXT-INDENT: 2em">oReq.send&nbsp;strA </P>
<P style="TEXT-INDENT: 2em">&lt;/ScRIPT&gt;</P>
<P style="TEXT-INDENT: 2em">（在这里俺把前面的JavaScript的代码改成了VBScript，不是吃饱了撑的没事干，原因见后）</P>
<P style="TEXT-INDENT: 2em">Part II.正确显示得到的中文内容</P>
<P style="TEXT-INDENT: 2em">OK，如果你在Server端把Form的内容写到<A href="http://www.chinahtml.com/databases/">数据库</A>/文件的话，你在那里看到的中文毫无问题，但是，假如你想看看Server的Response ——问题来了：如果Response的结果不是XML，XMLHTTP.responseXML里当然是不会有东东的，那就用responseText好了，在代码的最后加一句：</P>
<P style="TEXT-INDENT: 2em">alert(oReq.responseText)</P>
<P style="TEXT-INDENT: 2em">看看俺们辛勤劳动的结果 :P</P>
<P style="TEXT-INDENT: 2em">但是但是.....怎么所有的中文全变成了方格? （我打不出来，有兴趣自己去试，也不用Post，Get一个含有中文的网页就可以发现了。）</P>
<P style="TEXT-INDENT: 2em">原因很简单：XMLHTTP得到Response时假定Response是UTF8编码的，如果Response是XML，那还可以通过encoding 来指定编码，但HTML就不行了。（见鬼的GB2312，再次打倒！）所以它把含GB2312编码的HTML当成UTF8格式，不出错才有鬼！</P>
<P style="TEXT-INDENT: 2em">不过好在还有补救的办法：XMLHTTP的responseBody 属性里包含的可是未解码的Resonse——"a raw undecoded bytes as received directly from the server" ：），唯一的问题是，responseBody返回的是一个unsigned bytes数组，我们怎么去访问它，怎么把它转换成BSTR？</P>
<P style="TEXT-INDENT: 2em">这就是为什么我在上面把代码改成VBScript的原因——VBScript Can do it,but JavaScript Cannot!</P>
<P style="TEXT-INDENT: 2em">代码见下：</P>
<P style="TEXT-INDENT: 2em">&lt;SCRIPT&nbsp;language="VBScript"&gt; </P>
<P style="TEXT-INDENT: 2em">Function&nbsp;URLEncoding(vstrIn) </P>
<P style="TEXT-INDENT: 2em">strReturn&nbsp;=&nbsp;"" </P>
<P style="TEXT-INDENT: 2em">For&nbsp;i&nbsp;=&nbsp;1&nbsp;To&nbsp;Len(vstrIn) </P>
<P style="TEXT-INDENT: 2em">ThisChr&nbsp;=&nbsp;Mid(vStrIn,i,1) </P>
<P style="TEXT-INDENT: 2em">If&nbsp;Abs(Asc(ThisChr))&nbsp;&lt;&nbsp;&amp;HFF&nbsp;Then </P>
<P style="TEXT-INDENT: 2em">strReturn&nbsp;=&nbsp;strReturn&nbsp;&amp;&nbsp;ThisChr </P>
<P style="TEXT-INDENT: 2em">Else </P>
<P style="TEXT-INDENT: 2em">innerCode&nbsp;=&nbsp;Asc(ThisChr) </P>
<P style="TEXT-INDENT: 2em">If&nbsp;innerCode&nbsp;&lt;&nbsp;0&nbsp;Then </P>
<P style="TEXT-INDENT: 2em">innerCode&nbsp;=&nbsp;innerCode&nbsp;+&nbsp;&amp;H10000 </P>
<P style="TEXT-INDENT: 2em">End&nbsp;If </P>
<P style="TEXT-INDENT: 2em">Hight8&nbsp;=&nbsp;(innerCode&nbsp;And&nbsp;&amp;HFF00)\&nbsp;&amp;HFF </P>
<P style="TEXT-INDENT: 2em">Low8&nbsp;=&nbsp;innerCode&nbsp;And&nbsp;&amp;HFF </P>
<P style="TEXT-INDENT: 2em">strReturn&nbsp;=&nbsp;strReturn&nbsp;&amp;&nbsp;"%"&nbsp;&amp;&nbsp;Hex(Hight8)&nbsp;&amp;&nbsp;"%"&nbsp;&amp;&nbsp;Hex(Low8) </P>
<P style="TEXT-INDENT: 2em">End&nbsp;If </P>
<P style="TEXT-INDENT: 2em">Next </P>
<P style="TEXT-INDENT: 2em">URLEncoding&nbsp;=&nbsp;strReturn </P>
<P style="TEXT-INDENT: 2em">End&nbsp;Function </P>
<P style="TEXT-INDENT: 2em">Function&nbsp;bytes2BSTR(vIn) </P>
<P style="TEXT-INDENT: 2em">strReturn&nbsp;=&nbsp;"" </P>
<P style="TEXT-INDENT: 2em">For&nbsp;i&nbsp;=&nbsp;1&nbsp;To&nbsp;LenB(vIn) </P>
<P style="TEXT-INDENT: 2em">ThisCharCode&nbsp;=&nbsp;AscB(MidB(vIn,i,1)) </P>
<P style="TEXT-INDENT: 2em">If&nbsp;ThisCharCode&nbsp;&lt;&nbsp;&amp;H80&nbsp;Then </P>
<P style="TEXT-INDENT: 2em">strReturn&nbsp;=&nbsp;strReturn&nbsp;&amp;&nbsp;Chr(ThisCharCode) </P>
<P style="TEXT-INDENT: 2em">Else </P>
<P style="TEXT-INDENT: 2em">NextCharCode&nbsp;=&nbsp;AscB(MidB(vIn,i+1,1)) </P>
<P style="TEXT-INDENT: 2em">strReturn&nbsp;=&nbsp;strReturn&nbsp;&amp;&nbsp;Chr(CLng(ThisCharCode)&nbsp;*&nbsp;&amp;H100&nbsp;+&nbsp;CInt(NextCharCode)) </P>
<P style="TEXT-INDENT: 2em">i&nbsp;=&nbsp;i&nbsp;+&nbsp;1 </P>
<P style="TEXT-INDENT: 2em">End&nbsp;If </P>
<P style="TEXT-INDENT: 2em">Next </P>
<P style="TEXT-INDENT: 2em">bytes2BSTR&nbsp;=&nbsp;strReturn </P>
<P style="TEXT-INDENT: 2em">End&nbsp;Function </P>
<P style="TEXT-INDENT: 2em">strA&nbsp;=&nbsp;URLEncoding("submit1=Submit&amp;text1=中文") </P>
<P style="TEXT-INDENT: 2em">oReq&nbsp;=&nbsp;CreateObject("MSXML2.XMLHTTP") </P>
<P style="TEXT-INDENT: 2em">oReq.open&nbsp;"POST","http://ServerName/VDir/TstResult.asp",false </P>
<P style="TEXT-INDENT: 2em">oReq.setRequestHeader&nbsp;"Content-Length",Len(strA) </P>
<P style="TEXT-INDENT: 2em">oReq.setRequestHeader&nbsp;"CONTENT-TYPE","application/x-www-form-urlencoded" </P>
<P style="TEXT-INDENT: 2em">oReq.send&nbsp;strA </P>
<P style="TEXT-INDENT: 2em">alert&nbsp;bytes2BSTR(oReq.responseBody) </P>
<P style="TEXT-INDENT: 2em">&lt;/ScRIPT&gt;</P>
<P style="TEXT-INDENT: 2em">是不是很简单啊，用这个再试试看？一切OK！</P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/3747597220084994453745</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/3747597220084994453745</guid>
    <pubDate>Fri, 9 May 2008 21:44:53 +0800</pubDate>
    <dcterms:modified>2008-05-09T21:56:46+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[ajax入门(3)]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/3747597220084994213723</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">在这个关于AJAX系列的第三部分中，我们将学习如何使用AJAX与服务端进行写作以及这些技术如何产生强大的web应用程序。如果你对学习如何构建类似GMail或者Google Maps的web程序感兴趣的话，这是一篇基础的入门（虽然那两个东东会比我们在这篇文章中提及的内容复杂的多）。在这篇文章中，我使用PHP作为服务端语言，但AJAX能够和任何服务端语言进行很好的兼容，所以你尽可以选择你所钟爱的任何语言！ </P>
<P style="TEXT-INDENT: 2em">　　我们还是从我们上一篇文章的代码（喏，就在上面）开始我们的学习，你可以去阅读它来作为参考。</P>
<P style="TEXT-INDENT: 2em">　　这里就是这个HTML页面（带js）：</P>
<P style="TEXT-INDENT: 2em">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"</P>
<P style="TEXT-INDENT: 2em">&nbsp;"http://www.w3.org/TR/html4/strict.dtd"&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;html lang="zh-cn" dir="ltr"&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&lt;head&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;title&gt;如何使用ajax开发web应用程序--示例&lt;/title&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;script type="text/javascript"&gt;&lt;!--</P>
<P style="TEXT-INDENT: 2em">&nbsp; function ajaxRead(file){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; var xmlObj = null;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; if(window.XMLHttpRequest){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlObj = new XMLHttpRequest();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; } else if(window.ActiveXObject){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlObj = new ActiveXObject("Microsoft.XMLHTTP");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; } else {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; xmlObj.onreadystatechange = function(){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(xmlObj.readyState == 4){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processXML(xmlObj.responseXML);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; xmlObj.open ('GET', file, true);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; xmlObj.send ('');</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; function processXML(obj){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; var dataArray = obj.getElementsByTagName('pets')[0].childNodes;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; var dataArrayLen = dataArray.length;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; var insertData = '&lt;table&gt;&lt;tr&gt;&lt;th&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; + 'Pets&lt;/th&gt;&lt;th&gt;Tasks&lt;/th&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; for (var i=0; i&lt;dataArrayLen; i++){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; if(dataArray[i].tagName){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;tr&gt;&lt;td&gt;' + dataArray[i].tagName + '&lt;/td&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +&nbsp; '&lt;td&gt;' + dataArray[i].getAttribute('tasks') + '&lt;/td&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; insertData += '&lt;/table&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; document.getElementById ('dataArea').innerHTML = insertData;</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; //--&gt;&lt;/script&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;style type="text/css"&gt;&lt;!--</P>
<P style="TEXT-INDENT: 2em">&nbsp; table, tr, th, td {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; border: solid 1px #000;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; border-collapse: collapse;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; padding: 5px;</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; --&gt;&lt;/style&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&lt;/head&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&lt;body&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;h1&gt;使用Ajax开发web应用程序&lt;/h1&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;p&gt;这个页面演示了AJAX技术如何通过动态读取一个远程文件来更新一个网页的内容－－不需要任何网页的重新加载。注意：这个例子对于禁止js的用户来说没有效果。&lt;/p&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;p&gt;这个页面将演示如从取回并处理成组的XML数据。被取回的数据将会以表格形式输出到底下。</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;a href="#" onclick="ajaxRead('data_3.php'); return false"&gt;查看演示&lt;/a&gt;.&lt;/p&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;div id="dataArea"&gt;&lt;/div&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&lt;/body&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;/html&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; </P>
<P style="TEXT-INDENT: 2em">　　(Sheneyan注：示例就不提供了，参考底下说明即可。)</P>
<P style="TEXT-INDENT: 2em">　　这只是输出结果，我们准备从一个mysql数据库中获取这些信息。从现在起，我们可以直接在我们的数据库中修改数据而不是手动修改XML文件。用AJAX通过PHP来取得数据，并将它获取到一个页面上－－所有这些，仍然不需要重新加载网页。</P>
<P style="TEXT-INDENT: 2em">　　第一步是连接到mysql去获取数据。这篇文章的重点在javascript，所以我不会解释下面的代码如何工作，你需要自己去了解如何连接mysql数据库。</P>
<P style="TEXT-INDENT: 2em">&lt;?php</P>
<P style="TEXT-INDENT: 2em">&nbsp;$user = "admin";</P>
<P style="TEXT-INDENT: 2em">&nbsp;$pass = "adminpass";</P>
<P style="TEXT-INDENT: 2em">&nbsp;$host = "localhost";</P>
<P style="TEXT-INDENT: 2em">&nbsp;$conn = mysql_connect($host, $user, $pass) or die("Unable to connect to MySQL.");</P>
<P style="TEXT-INDENT: 2em">&nbsp;$db&nbsp;&nbsp; = mysql_select_db("pets",$conn) or die("Could not select the database.");</P>
<P style="TEXT-INDENT: 2em">&nbsp;mysql_close($db);</P>
<P style="TEXT-INDENT: 2em">?&gt;</P>
<P style="TEXT-INDENT: 2em">　　只要你连接了数据库，你可以通过底下的查询来获取信息：</P>
<P style="TEXT-INDENT: 2em">&lt;?php</P>
<P style="TEXT-INDENT: 2em">&nbsp;$user = "admin";</P>
<P style="TEXT-INDENT: 2em">&nbsp;$pass = "adminpass";</P>
<P style="TEXT-INDENT: 2em">&nbsp;$host = "localhost";</P>
<P style="TEXT-INDENT: 2em">&nbsp;$conn = mysql_connect($host, $user, $pass) or die("Unable to connect to MySQL.");</P>
<P style="TEXT-INDENT: 2em">&nbsp;$db&nbsp;&nbsp; = mysql_select_db("pets",$conn) or die("Could not select the database.");</P>
<P style="TEXT-INDENT: 2em">&nbsp;$result = mysql_query("SELECT * FROM `pets`");</P>
<P style="TEXT-INDENT: 2em">&nbsp; if(mysql_num_rows ($result) == 0){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; die ('Error: no data found in the database.');</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; while ($row = mysql_fetch_assoc($result)){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; echo 'Pet: '.$row['pet'].', tasks: '.$row['tasks'].'. ';</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">&nbsp;mysql_close($db);</P>
<P style="TEXT-INDENT: 2em">?&gt;</P>
<P style="TEXT-INDENT: 2em">　　这段代码给了你需要的信息，但它输出并不正确。我们需要修改这PHP代码来分隔数据为XML，而不是纯文本。为了实现这个目标我们得作几个修改。</P>
<P style="TEXT-INDENT: 2em">&lt;?php</P>
<P style="TEXT-INDENT: 2em">&nbsp;header('Content-Type: text/xml');//编号1</P>
<P style="TEXT-INDENT: 2em">&nbsp;echo '&lt;?xml version="1.0" encoding="UTF-8"?&gt;';//编号2</P>
<P style="TEXT-INDENT: 2em">&nbsp;echo "\n&lt;data&gt;\n&lt;pets&gt;\n";//编号3</P>
<P style="TEXT-INDENT: 2em">&nbsp;$user = "admin";</P>
<P style="TEXT-INDENT: 2em">&nbsp;$pass = "adminpass";</P>
<P style="TEXT-INDENT: 2em">&nbsp;$host = "localhost";</P>
<P style="TEXT-INDENT: 2em">&nbsp;$conn = mysql_connect($host, $user, $pass) or die("无法连接mysql.");</P>
<P style="TEXT-INDENT: 2em">&nbsp;$db&nbsp;&nbsp; = mysql_select_db("pets",$conn) or die("无法选择数据库.");</P>
<P style="TEXT-INDENT: 2em">&nbsp;$result = mysql_query("SELECT * FROM `pets`");</P>
<P style="TEXT-INDENT: 2em">&nbsp; if(mysql_num_rows ($result) == 0){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; die ('Error: 数据库没有数据.');</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; while ($row = mysql_fetch_assoc($result)){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; echo '&lt;'.$row['pet'].' tasks="'.$row['tasks'].'" /&gt;'."\n";//编号4</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; echo "&lt;/pets&gt;\n&lt;/data&gt;";//编号5</P>
<P style="TEXT-INDENT: 2em">&nbsp;mysql_close($db);</P>
<P style="TEXT-INDENT: 2em">?&gt;</P>
<P style="TEXT-INDENT: 2em">　　让我们从上面开始，一次一行的来分析它是如何输出XML的.我给每一行都加了注释标记以便于更好的对应理解(原文是I've color-coded each line to make it easier to understand,我懒得上色,就改成用编号了)</P>
<P style="TEXT-INDENT: 2em">　　编号1:这部分代码发送一个http头来让用户客户端明白这个php文件输出的是一个XML。这就是为什么你在你的浏览器里看这个文档的时候它以一个XML文件的形式展现，即使你的文件有一个“.php”后缀。</P>
<P style="TEXT-INDENT: 2em">　　编号2:这部分的代码输出了XML声明。这是我之前展示给你看的XML的第一行。</P>
<P style="TEXT-INDENT: 2em">　　编号3:这部分的代码输出的最开始的两个标签：我们的根标签，&lt;data&gt;和我们用来放置所有宠物的&lt;pets&gt;标签。</P>
<P style="TEXT-INDENT: 2em">　　编号4:这部分的代码最困难的。这里包含了一个循环用来遍历你数据库里所有的数据。每次循环，它会输出一个新的节点，这个节点用每一种动物作为标签名以及一个"任务"属性。例如，如果你数据库中的第一只宠物是“猫”而且它相应的任务字段是“喂食, 饮水, 抓跳蚤”，那php将输出在XML文档中输出 &lt;猫 tasks="喂食, 饮水, 抓跳蚤" /&gt; 。这个“\n” 部分只是在结尾插入一个新行，保证这个XML代码不至于都在同一行。</P>
<P style="TEXT-INDENT: 2em">　　编号5:这部分的代码结束了 我们开始时打开的&lt;/pets&gt; 和 &lt;/data&gt; 节点。因为XML必须是格式良好的（well-formed），所以我们必须认真对待这部分以确认我们的程序能够正确运行。</P>
<P style="TEXT-INDENT: 2em">　　现在我们已经让PHP输出XML了，我们现在所要作的就是登录我们的mysql数据库，并进行我们所需要的修改，来更新这个XML。很酷，不是吗？我们仍然能够使用上一篇文章中的js脚本来获取代码，因为XML输出和之前的完全一样。</P>
<P style="TEXT-INDENT: 2em">　　结论</P>
<P style="TEXT-INDENT: 2em">　　你可以再进一步的扩展，使用XML来保存和获取数据。换句话说，你能够使用php来写你的XML文件，然后让javascript来读。用ajax，你也能够定时的检查xml文件是否已经更改而且，如果XML已经更新，也可以更新本页面。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">编者注：本文的原作者介绍的是在以php为后台的环境下的ajax；但是ajax本身不是一种新鲜的技术，看起来是一种思路；在不同的后台之间都有很多共同的地方。</P>
<P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">学习ajax，需要有很好的javascript基础；另外需要熟练使用xmlhttp对象.</P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/3747597220084994213723</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/3747597220084994213723</guid>
    <pubDate>Fri, 9 May 2008 21:42:13 +0800</pubDate>
    <dcterms:modified>2008-05-09T21:56:04+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[ajax入门(2)]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/3747597220084994033328</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">在上一篇文章中，我们讨论了如何通过javascript从一个远程XML文件中取得数据。在这篇文章中，我们将学会怎样对数据作更复杂的处理。作为一个示例，我们会准备一组XML数据，将数据分割成独立的片断并以不同的方式展示这些片断（取决于它们是如何被标识的）。 </P>
<P style="TEXT-INDENT: 2em">　　这篇文章是建立在上一篇文章中构造的示例代码的基础之上，所以如果你不能理解我们现在的代码，你可以回过头去读第一篇文章（sheneyan注：就在上面）。</P>
<P style="TEXT-INDENT: 2em">开始～</P>
<P style="TEXT-INDENT: 2em">　　让我们开始我们的第一步：构造XML。我们准备写一个XML文档，它组织了一系列准备让javascript处理的数据，所以我们将一起组织一些节点和子节点（或者，元素和子元素）。在这个例子里，我们将使用一些家庭宠物的名字：</P>
<P style="TEXT-INDENT: 2em">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;data&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;pets&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; &lt;pet&gt;猫&lt;/pet&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; &lt;pet&gt;狗&lt;/pet&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; &lt;pet&gt;鱼&lt;/pet&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/pets&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;/data&gt; </P>
<P style="TEXT-INDENT: 2em">　　在上面，我们有这个XML声明（标明这个文档是一个XML 1.0 文档，使用UTF-8编码），一个根元素（&lt;data&gt;）将下面所有的元素组合在一起，一个&lt;pets&gt;元素组织了所有的宠物，然后一个&lt;pet&gt;节点对应一只宠物。为了指定每一只宠物是什么类型的动物，我们在&lt;pet&gt;元素中设置了文本节点：猫，狗，鱼。</P>
<P style="TEXT-INDENT: 2em">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"</P>
<P style="TEXT-INDENT: 2em">&nbsp; "http://www.w3.org/TR/html4/strict.dtd"&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;html lang="zh" dir="ltr"&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;head&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312"&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;title&gt;使用Ajax开发Web应用程序 - 示例&lt;/title&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;script type="text/javascript"&gt;&lt;!--</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; function ajaxRead(file){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var xmlObj = null;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(window.XMLHttpRequest){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlObj = new XMLHttpRequest();</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if(window.ActiveXObject){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlObj = new ActiveXObject("Microsoft.XMLHTTP");</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlObj.onreadystatechange = function(){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(xmlObj.readyState == 4){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processXML(xmlObj.responseXML);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlObj.open ('GET', file, true);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlObj.send ('');</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; function processXML(obj){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dataArray = obj.getElementsByTagName('pet');</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dataArrayLen = dataArray.length;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var insertData = '&lt;table style="width:150px; border: solid 1px #000"&gt;&lt;tr&gt;&lt;th&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + 'Pets&lt;/th&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i=0; i&lt;dataArrayLen; i++){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;tr&gt;&lt;td&gt;' + dataArray[i].firstChild.data + '&lt;/td&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;/table&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById ('dataArea').innerHTML = insertData;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; //--&gt;&lt;/script&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/head&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;body&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;h1&gt;使用Ajax开发web应用程序&lt;/h1&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;p&gt;这个页面演示了AJAX技术如何通过动态读取一个远程文件来更新一个网页的内容－－不需要任何网页的重新加载。注意：这个例子对于禁止js的用户来说没有效果。&lt;/p&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;p&gt;这个页面将演示如从取回并处理成组的XML数据。被取回的数据将会以表格形式输出到底下。</P>
<P style="TEXT-INDENT: 2em">&lt;a href="#" onclick="ajaxRead('data_2.xml'); return false"&gt;查看演示&lt;/a&gt;.&lt;/p&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;div id="dataArea"&gt;&lt;/div&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/body&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;/html&gt; </P>
<P style="TEXT-INDENT: 2em">你会注意到我们和上次一样以同样的方式（通过一个超链接）调用了这个函数，而且我们将数据放入一个DIV（这次这个东东叫做“dataArea”）。这个ajaxRead()函数和上次很接近，除了一点不同：onreadystatechange函数。让我们先看一下这个函数： </P>
<P style="TEXT-INDENT: 2em">xmlObj.onreadystatechange = function(){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(xmlObj.readyState == 4){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processXML(xmlObj.responseXML);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">　　我们取消了updateObj函数并用一个叫做processXML()的新函数来代替它。这个函数将得到XML文档本身（也就是被ajaxRead函数取回的）并处理它。（这“XML文档本身”我指的是参数“xmlObj.responseXML”）</P>
<P style="TEXT-INDENT: 2em">　　现在让我们分析一下这个函数processXML。下面是它的代码：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function processXML(obj){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dataArray = obj.getElementsByTagName('pet');</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dataArrayLen = dataArray.length;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var insertData = '&lt;table style="width:150px; border: solid 1px #000"&gt;&lt;tr&gt;&lt;th&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + 'Pets&lt;/th&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i=0; i&lt;dataArrayLen; i++){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;tr&gt;&lt;td&gt;' + dataArray[i].firstChild.data + '&lt;/td&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;/table&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById ('dataArea').innerHTML = insertData;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; }&nbsp; </P>
<P style="TEXT-INDENT: 2em">　　首先，我们定义了一些变量。“dataArray”作为所有&lt;pet&gt;节点的数组（不是节点数据，只是节点）。“dataArrayLen”是这个数组的长度，用于我们的循环。“insertData”则是一个表格的开头的HTML。</P>
<P style="TEXT-INDENT: 2em">　　我们的第二步则是遍历所有的&lt;pet&gt;元素（通过变量“dataArray”）并将数据添加到变量insertData中。这里我们会创建一个表格行，插入一个表格数据节点(td)进去，再将每一个&lt;pet&gt;元素的文本包含进这个表格数据节点，并将这些都添加进变量“insertData”。因此，每循环一次，变量insertData将添加一行包含三个宠物中之一名称的新数据。</P>
<P style="TEXT-INDENT: 2em">　　新数据行添加完后，我们插入一个“&lt;/table&gt;”结束标签到变量“insertData”。这完成了这个表格，然后我只剩这最后一步来达成我们的目标：我们需要将这个表格放到页面上。幸运的是，我们得感谢innerHTML属性，这很简单。我们通过函数document.getElementById()取得DIV“dataArea”并将变量“insertData”中的HTML插进去。嗯，这个表格冒出来了！</P>
<P style="TEXT-INDENT: 2em">　　我们继续之前……</P>
<P style="TEXT-INDENT: 2em">　　我得指出两点：</P>
<P style="TEXT-INDENT: 2em">　　首先，你会注意到我们并没有使用节点&lt;pets&gt;。这事因为我们只有一个数据组（&lt;pets&gt;）以及后来所有的元素（每一个&lt;pet&gt;元素）；这些子节点包含了不同的数据但它们有相同的名字。在这个例子中，这个节点能够被忽略。然而，将所有的元素&lt;pet&gt;放进&lt;pets&gt;元素还是比较好，而不是让这些&lt;pet&gt;元素自己散放（但仍然在data元素里面）。</P>
<P style="TEXT-INDENT: 2em">　　另外一种方式是给每一个宠物放一个指定的标签，比如：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&lt;?xml version="1.0" encoding="UTF-8"?&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;data&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;pets&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;猫 /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;狗 /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;鱼 /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/pets&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;/data&gt;&nbsp; </P>
<P style="TEXT-INDENT: 2em">　　然后我们能够遍历元素&lt;pets&gt;里的节点。这个processXML函数看起来就像这样：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; function processXML(obj){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dataArray = obj.getElementsByTagName('pets')[0].childNodes;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dataArrayLen = dataArray.length;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var insertData = '&lt;table style="width:150px; border: solid 1px #000"&gt;&lt;tr&gt;&lt;th&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; + 'Pets&lt;/th&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; for (var i=0; i&lt;dataArrayLen; i++){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(dataArray[i].tagName){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;tr&gt;&lt;td&gt;' + dataArray[i].tagName + '&lt;/td&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; insertData += '&lt;/table&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; document.getElementById ('dataArea').innerHTML = insertData;</P>
<P style="TEXT-INDENT: 2em">&nbsp; } </P>
<P style="TEXT-INDENT: 2em">这里所作的修改就是我们指向了&lt;pets&gt;组元素（这个“[0]”意味这是第一个，即使它就是唯一的那一个）以及它的子节点（元素&lt;猫 /&gt;，&lt;狗 /&gt;，&lt;鱼 /&gt;）。因为文本元素分割了这几个元素（空格被认为是一个节点），我们需要确定只有那些有标签名的节点（嗯，也就是只有标签）通过。然后我们输出每一个标签的名字。因为每一个标签名是一个宠物，我们不需要取得每一个节点的数据－节点名本身已经足够。去看一下它是怎么工作的吧。 </P>
<P style="TEXT-INDENT: 2em">　　还有另外一种方式来完成我们上面的工作，就是给每一个&lt;pet&gt;节点设置一个属性值。你的XML文档看起来就像这样：</P>
<P style="TEXT-INDENT: 2em">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;data&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;pets&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;pet type="猫" /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;pet type="狗" /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;pet type="鱼" /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/pets&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;/data&gt;&nbsp; </P>
<P style="TEXT-INDENT: 2em">　　你只需要稍微修改一下你的processXML函数，它变成这样子了：</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; function processXML(obj){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dataArray = obj.getElementsByTagName('pet');</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dataArrayLen = dataArray.length;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var insertData = '&lt;table style="width:150px; border: solid 1px #000"&gt;&lt;tr&gt;&lt;th&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + 'Pets&lt;/th&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; for (var i=0; i&lt;dataArrayLen; i++){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;tr&gt;&lt;td&gt;' + dataArray[i].getAttribute('type') + '&lt;/td&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;/table&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById ('dataArea').innerHTML = insertData;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; } </P>
<P style="TEXT-INDENT: 2em">　　关键的不同在于我们通过dataArray[i].getAttribute('type')取得值，它返回了当前&lt;pet&gt;节点的“type”属性的值。</P>
<P style="TEXT-INDENT: 2em">继续...</P>
<P style="TEXT-INDENT: 2em">　　现在我们已经知道了一些从一个单独的XML数据组中取回数据的有效方法，让我们看看如何从多个组中取回数据。和只是列出一个pets所拥有的内容不同，我们假设我们有一个针对我们宠物的日课表。因为它们都有不同的需要，每一只宠物都得仔细的照顾。面对这种情况，动物的看管员需要一个每日依据。现在来让我们将这些放入一个良好格式的XML：</P>
<P style="TEXT-INDENT: 2em">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;data&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;pets&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;pet&gt;Cat</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task&gt;Feed&lt;/task&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task&gt;Water&lt;/task&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task&gt;Comb out fleas&lt;/task&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;/pet&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;pet&gt;Dog</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task&gt;Feed&lt;/task&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task&gt;Water&lt;/task&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task&gt;Put outside&lt;/task&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;/pet&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;pet&gt;Fish</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task&gt;Feed&lt;/task&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task&gt;Check oxygen, water purity, etc.&lt;/task&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;/pet&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/pets&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;/data&gt; </P>
<P style="TEXT-INDENT: 2em">　　也许这个看起来很奇怪，但这就是我们正在创建的子组(sub-group)。每一个&lt;pet&gt;元素都是一个组&lt;pets&gt;的子组，而每一个&lt;task&gt;则是每一个&lt;pet&gt;组的子元素。</P>
<P style="TEXT-INDENT: 2em">　　在我继续之前，你也许希望将你的表格用一些css美化一下，比如：</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;style type="text/css"&gt;&lt;!--</P>
<P style="TEXT-INDENT: 2em">&nbsp; table, tr, th, td {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; border: solid 1px #000;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; border-collapse: collapse;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; padding: 5px;</P>
<P style="TEXT-INDENT: 2em">&nbsp;}</P>
<P style="TEXT-INDENT: 2em">--&gt;&lt;/style&gt; </P>
<P style="TEXT-INDENT: 2em">　　这让这个表格更容易读取。现在让我们去研究函数processXML：</P>
<P style="TEXT-INDENT: 2em">&nbsp; function processXML(obj){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var dataArray = obj.getElementsByTagName('pet');</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var dataArrayLen = dataArray.length;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var subAry, subAryLen;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var insertData = '&lt;table&gt;&lt;tr&gt;&lt;th&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + 'Pets&lt;/th&gt;&lt;th&gt;Tasks&lt;/th&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; for (var i=0; i&lt;dataArrayLen; i++){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;tr&gt;&lt;td&gt;' + dataArray[i].firstChild.data + '&lt;/td&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subAry = dataArray[i].getElementsByTagName('task');</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subAryLen = subAry.length;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;td&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(var j=0; j&lt;subAryLen; j++){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += subAry[j].firstChild.data;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( subAryLen != j+1 ) { insertData += ', '; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;/td&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; insertData += '&lt;/table&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp; document.getElementById ('dataArea').innerHTML = insertData;</P>
<P style="TEXT-INDENT: 2em">新增加的内容，首先是两个新变量的声明：“subAry”和“subAryLen”。它们和之前的变量“dataArray”和“dataArrayLen”类似，除了它们指向不同的数组（特别是它们将指向那些“task”元素－当“dataArray”和“dataArrayLen”指向“pet”元素的时候）。 </P>
<P style="TEXT-INDENT: 2em">　　我们也改变了变量“insertData”的初始值－我们增加了一个表格头（&lt;th&gt;）给我们的“tasks”字段。</P>
<P style="TEXT-INDENT: 2em">　　下一步改变在于循环：我们把值赋给subAry和subAryLen变量。变量subAry成为当前&lt;pet&gt;的&lt;task&gt;元素的数组。变量subAryLen成为这个数组的长度，直到这个数组发生变化（当外部循环走到下一个&lt;pet&gt;时）。</P>
<P style="TEXT-INDENT: 2em">　　我们创建了一个内嵌的循环来处理所有的&lt;task&gt;元素，一次一个。大概来说，我们创建一个新的数据格，放进一个用逗号分隔的任务列表，然后关闭数据表格以及当前行。尤其，这些&lt;task&gt;元素节点数据（任务本身，比如，“喂食”）放置入变量“insertData”里的数据格。</P>
<P style="TEXT-INDENT: 2em">　　接下来，我们检验当前&lt;pet&gt;是否有其它更多的task。如果还有，我们增加一个逗号（，）到变量insertData来让每一个任务使用一个逗号分隔（“a, b, c”，而不是“a, b, c,”－注意，最后一个逗号在第二个任务那里，所以我们不需要）。这个工作在我们取得subAry数组长度的时候（给循环的“j”变量加1）就完成了。因为这个循环会在下一个循环的时候把变量“j”递增1,“j”会比它这次检验时还多1。因此，如果“j+1”（或者，“当循环再次开始的时候j的值”）等于subAryLen（当前&lt;pet&gt;节点的&lt;task&gt;节点数目），这个循环将停止。如果循环不再运行，我们就不再添加新的逗号来分隔任务。所以如果“j+1”不等于subAryLen，我们直到我们可以安全的加入逗号到“insertData”，为下一个&lt;task&gt;作准备。</P>
<P style="TEXT-INDENT: 2em">　　一旦内循环结束，我们关闭task数据格以及pet行。外部循环会重新开始创建一个新行以及移动到下一个&lt;pet&gt;。这个处理一直进行到所有的&lt;pet&gt;元素（以及每一个pet的所有&lt;task&gt;元素）都被处理完。</P>
<P style="TEXT-INDENT: 2em">　　有其他方法吗？</P>
<P style="TEXT-INDENT: 2em">　　你也许会想：“那javascript变得相当复杂了，但它只会随着XML越来越复杂而跟着变复杂，也许我们能够简化XML，然后，简化javascript”。如果你这么想，很棒，因为你完全正确。我之前展示的不同方法之一，我详细说明的那个也许能够成为最合适的。我们怎么使用属性来对应每一只宠物以及相应任务？XML看起来会变成怎样？</P>
<P style="TEXT-INDENT: 2em">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;data&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;pets&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;pet type="Cat" tasks="Feed, Water, Comb out fleas" /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;pet type="Dog" tasks="Feed, Water, Put outside" /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;pet type="Fish" tasks="Feed, Check oxygen, water purity, etc." /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/pets&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;/data&gt;&nbsp; </P>
<P style="TEXT-INDENT: 2em">　　哇哦！看起来简单多了。让我们看看我们的processXML函数如何修改：</P>
<P style="TEXT-INDENT: 2em">&nbsp; function processXML(obj){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var dataArray = obj.getElementsByTagName('pet');</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var dataArrayLen = dataArray.length;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var insertData = '&lt;table&gt;&lt;tr&gt;&lt;th&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; + 'Pets&lt;/th&gt;&lt;th&gt;Tasks&lt;/th&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; for (var i=0; i&lt;dataArrayLen; i++){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;tr&gt;&lt;td&gt;' + dataArray[i].getAttribute('type')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + '&lt;/td&gt;'</P>
<P style="TEXT-INDENT: 2em">+ '&lt;td&gt;' + dataArray[i].getAttribute('tasks') + '&lt;/td&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; insertData += '&lt;/table&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; document.getElementById ('dataArea').innerHTML = insertData;</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">　</P>
<P style="TEXT-INDENT: 2em">　　就像你猜的一样，函数简单多了。因为代码变得简单，它也会变得更有效率。和我们比较老的函数的唯一的不同在于这个变量insertData现在插入更多的HTML，尤其是两个新变量“type”和“tasks”。就如我们较早之前所学的，那些属性是我们从XML文档的&lt;pet&gt;元素中取得的，而且每个pet的属性都有不同的值。对于你自己修改这个XML文件以适应你的进度的变动来说也许是最简单的方法。例如，如果你最终把你的猫身上的跳蚤抓光了，你只要简单从你的猫的每日任务表中把“减少跳蚤数量”删除，然而在之前我们使用的XML中，实现起来也许会觉得糊里糊涂。</P>
<P style="TEXT-INDENT: 2em">　　最后的XML格式化的方法是将两部分混合。现在，我们将使用属性和不同的标签。让我们看一下示例XML：</P>
<P style="TEXT-INDENT: 2em">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;data&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;pets&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;猫 tasks="喂食, 饮水, 减少跳蚤数量" /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;狗 tasks="喂食, 饮水, 带出去遛遛" /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;鱼 tasks="喂食, 检查氧气，水的纯度，其它" /&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/pets&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;/data&gt;&nbsp; </P>
<P style="TEXT-INDENT: 2em">　　这也许是最便于理解的XML。让我们分析一下我们为了让processXML函数运作起来所作的变更：</P>
<P style="TEXT-INDENT: 2em">function processXML(obj){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var dataArray = obj.getElementsByTagName('pets')[0].childNodes;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var dataArrayLen = dataArray.length;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; var insertData = '&lt;table&gt;&lt;tr&gt;&lt;th&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; + 'Pets&lt;/th&gt;&lt;th&gt;Tasks&lt;/th&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; for (var i=0; i&lt;dataArrayLen; i++){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(dataArray[i].tagName){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; insertData += '&lt;tr&gt;&lt;td&gt;' + dataArray[i].tagName + '&lt;/td&gt;'</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + '&lt;td&gt;' + dataArray[i].getAttribute('tasks') + '&lt;/td&gt;&lt;/tr&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; insertData += '&lt;/table&gt;';</P>
<P style="TEXT-INDENT: 2em">&nbsp; document.getElementById ('dataArea').innerHTML = insertData;</P>
<P style="TEXT-INDENT: 2em">} </P>
<P style="TEXT-INDENT: 2em">　　“dataArray”现在指向了&lt;pets&gt;的子节点，将它们作为一个数组对待（换句话说，dataArray现在是在&lt;pets&gt;节点内所有节点的数组）。这事因为每一个标签都不同（&lt;猫 /&gt;，&lt;狗 /&gt;，&lt;鱼 /&gt;），所以我们不能使用这些元素的名称来搜索它们（而之前我们可以使用&lt;pet&gt;，因为所有的元素都是&lt;pet&gt;）。</P>
<P style="TEXT-INDENT: 2em">　　还是一样，每个节点之间的有空格，所以在我们的处理过程中得排除掉文本节点。我们能够检验标签名是否存在－文本节点是节点但没有标签，而&lt;猫 /&gt;，&lt;狗 /&gt;，&lt;鱼 /&gt;节点都是标签。所以如果一个标签有名字，那我们能够将数据插入变量insertData。我们插入的数据是一个表格并有两个表格数据格。这第一个单元格是标签名，也就是宠物的类型（猫，狗或鱼），而第二个单元格则是指定动物的“tasks”属性值（比如“喂食或饮水”）。</P>
<P style="TEXT-INDENT: 2em">　　结束语</P>
<P style="TEXT-INDENT: 2em">　　在这篇文章里，我演示了这个例子的很多变化，你可以随意试验它们来检验哪个更适合你。只要记住一点，XML是“可扩展的”，所以没有“错误的”方法来组合你的数据，虽然经常有一个“最好的”方法。而且，要注意让你的XML保持格式良好。记住很多问题来自于忘记结束一个标签（比如&lt;狗 /&gt;而不是&lt;狗&gt;;除非这个节点中有数据，比如下面的&lt;狗&gt;这里有数据哦&lt;/狗&gt;）。</P>
<P style="TEXT-INDENT: 2em">　　我意图使XML和javascript的应用不糊涂而变得明朗。一步步的学习处理更多的数据，你能够将ajax运用于更大的用途。我希望看到ajax更多的应用于企业网站，及其它。</P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/3747597220084994033328</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/3747597220084994033328</guid>
    <pubDate>Fri, 9 May 2008 21:40:33 +0800</pubDate>
    <dcterms:modified>2008-05-09T21:56:43+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[ajax入门 (1)]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/374759722008499325997</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">在过去，由于为了获得新数据而不得不重新加载web页面（或者加载其他页面）导致web应用程序发展被限制。虽然有其他方法可用（不加载其他页面），但是这些技术都没有被很好地支持而且有bug成灾的趋向。在过去的几个月里，一个过去并不被广泛支持的技术已经被越来越多的web冲浪者（web surfers??是指浏览器还是浏览者？）所接受，它给了开发者更多的自由开发先进的web应用程序。这些通过javascript来异步取得xml数据的应用程序，被亲切的称为“Ajax应用程序”（Asynchronous Javascript and XML applications）。在这篇文章中，我将会解释如何通过Ajax来取回一个远程的XML文件并更新一个web page，并且随着这个系列的继续，我将讨论更多的方法，使用ajax技术将你的web应用程序提升到一个新的层次.</P>
<P style="TEXT-INDENT: 2em">　　这第一步就是创建一个带一些数据的XML文件。我们将这个文件命名为data.xml。它是一个简单的XML文件，而在一个真实的程序中，它会复杂许多，但对于我们的例子来说，简单明了是最合适地。</P>
<P style="TEXT-INDENT: 2em">&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;root&gt; &lt;data&gt; 这是一些示例数据，它被保存在一个XML文件中，并被JavaScript取回。 &lt;/data&gt; &lt;/root&gt;</P>
<P style="TEXT-INDENT: 2em">　　现在让我们创建一个简单的web页面包含一些示例数据。这个页面将是我们的js脚本所在，并且这个页面将会让用户们访问柄看到Ajax脚本的运行。我们把它命名为ajax.html</P>
<P style="TEXT-INDENT: 2em">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"</P>
<P style="TEXT-INDENT: 2em">&nbsp; "http://www.w3.org/TR/html4/strict.dtd"&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;html lang="zh" dir="ltr"&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;head&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312"&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;title&gt;使用ajax开发web应用程序 - 示例&lt;/title&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/head&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;body&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;h1&gt;使用ajax开发web应用程序&lt;/h1&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;p&gt;这个页面演示了AJAX技术如何通过动态读取一个远程文件来更新一个网页的内容－－不需要任何网页的重新加载。注意：这个例子对于禁止js的用户来说没有效果。&lt;/p&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;p id="xmlObj"&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; 这是一些示例数据，它是这个网页的默认数据 &lt;a href="data.xml"</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; title="查看这个XML数据." onclick="ajaxRead('data.xml'); this.style.display='none'; return false"&gt;查看XML数据.&lt;/a&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; &lt;/p&gt;</P>
<P style="TEXT-INDENT: 2em">&nbsp; &lt;/body&gt;</P>
<P style="TEXT-INDENT: 2em">&lt;/html&gt;</P>
<P style="TEXT-INDENT: 2em">　　注意，对于那些没有javascript的用户，我们直接链接到data.xml文件。对于那些允许运行javascript的用户，函数“ajaxRead”将被运行，这个链接被隐藏，并不会被转向到那个data.xml文件。函数“ajaxRead”现在还没定义。所以如果你要检验上面的示例代码，你会得到一个javascript错误。让我们继续并定义这个函数（还有其他的），让你能够看到ajax是如何工作的，下面的脚本要放到你的head标签里：</P>
<P style="TEXT-INDENT: 2em">&lt;script type="text/javascript"&gt;&lt;!--</P>
<P style="TEXT-INDENT: 2em">function ajaxRead(file){</P>
<P style="TEXT-INDENT: 2em">&nbsp; var xmlObj = null;</P>
<P style="TEXT-INDENT: 2em">&nbsp; if(window.XMLHttpRequest){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlObj = new XMLHttpRequest();</P>
<P style="TEXT-INDENT: 2em">&nbsp; } else if(window.ActiveXObject){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlObj = new ActiveXObject("Microsoft.XMLHTTP");</P>
<P style="TEXT-INDENT: 2em">&nbsp; } else {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; xmlObj.onreadystatechange = function(){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; if(xmlObj.readyState == 4){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateObj('xmlObj', xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; xmlObj.open ('GET', file, true);</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp; xmlObj.send ('');</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; function updateObj(obj, data){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; document.getElementById(obj).firstChild.data = data;</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">&nbsp; //--&gt;&lt;/script&gt;</P>
<P style="TEXT-INDENT: 2em">这堆代码有点多，让我们一点点的进行。第一个函数叫做“ajaxRead”－也就是我们在页面的“查看XML数据”链接中调用的函数，我们定义了一个“xmlObj”变量－这将作为客户端（用户正在查看的这个web页面）以及服务端（web站点本身）之间的中间件。我们在一个if/else块中定义这个对象： </P>
<P style="TEXT-INDENT: 2em">if(window.XMLHttpRequest){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; xmlObj = new XMLHttpRequest();</P>
<P style="TEXT-INDENT: 2em">} else if(window.ActiveXObject){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; xmlObj = new ActiveXObject("Microsoft.XMLHTTP");</P>
<P style="TEXT-INDENT: 2em">} else {</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp; return;</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">　　这只是一个对不同对象是否可用的测试－某些浏览器实现了不同的XMLHttpRequest对象，所以当我们定义“xmlObj”作为我们的XMLHttpRequest对象时，我们不得不根据浏览器所实现的来定义它。如果没有可用的XMLHttpRequest对象，我们将执行“return”语句结束这个函数以避免脚本错误。在大部分情况下，这个检验将返回一个XMLHttpRequest对象－这部分代码应该能够在绝大部分的浏览器上工作，除了少部分比较老的浏览器的异常情况（它能够工作在ie5.01上，但是在netscape4上会使函数终止）。</P>
<P style="TEXT-INDENT: 2em">　　接下来是这些代码块: </P>
<P style="TEXT-INDENT: 2em">xmlObj.onreadystatechange = function(){</P>
<P style="TEXT-INDENT: 2em">&nbsp; if(xmlObj.readyState == 4){</P>
<P style="TEXT-INDENT: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updateObj('xmlObj', xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);</P>
<P style="TEXT-INDENT: 2em">&nbsp; }</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">　　每次XMLHttpRequest的状态发生变化，事件“onreadystatechange”就会被触发。通过使用“xmlObj.onreadystatechange = function(){...}”我们能够创建一个函数并让它在这个XMLHttpRequest对象的状态每次发生改变的时候立刻运行。这里总共有五个状态，由0走到4。</P>
<P style="TEXT-INDENT: 2em">　　0 – 尚未初始化（在这个XMLHttpRequest开始前）</P>
<P style="TEXT-INDENT: 2em">　　1 – 加载（XMLHttpRequest初始化一结束）</P>
<P style="TEXT-INDENT: 2em">　　2 – 加载结束（XMLHttpRequest一从服务器上获得一个回应）</P>
<P style="TEXT-INDENT: 2em">　　3 – 交互（当XMLHttpRequest对象和服务器连接中）</P>
<P style="TEXT-INDENT: 2em">　　4 – 结束（当XMLHttpRequest被告知它已经完成了所有人物并结束运行）</P>
<P style="TEXT-INDENT: 2em">　　这第五个状态（数字4）就是我们能够确定数据已经可用的标志，所以我们检验这个xmlObj.readyState是否等于“4”来确定数据是否可用，如果是4，我们运行updateObj函数。这个函数带两个参数：一个当前web页面的元素ID（当前web页面中要更新的元素）以及用于填充这个元素的数据。这个函数的运行方式在稍后将更详细地解释。</P>
<P style="TEXT-INDENT: 2em">　　我们的web页面的p元素有一个id“xmlData”，这就是我们准备更新的段落。我们正在取得的数据来自于XML文件，但它有点复杂。这里是它如何工作的原理。</P>
<P style="TEXT-INDENT: 2em">　　xmlObj.responseXML属性是一个DOM对象 － 它很象“document”对象，除了它来自远程的XML文件。换句话说，如果你在data.xml中运行脚本，那xmlObj.responseXML就是一个“document”对象。因为我们知道这些，我们能够通过“getElementsByTagName”方法取得任何XML节点。数据包含在一个命名为“&lt;data&gt;”的XML节点中，所以我们的任务很简单：取得第一个（而且只有这一个）数据节点。因而，xmlObject.responseXML.getElementsByTagName("data")[0]返回XML文件中的第一个&lt;data&gt;节点。</P>
<P style="TEXT-INDENT: 2em">　　注意：它返回的是XML节点，而不是节点中的数据－这个数据必须通过访问XML节点的属性取得，这就是下一步要说的。</P>
<P style="TEXT-INDENT: 2em">　　接下来，取得数据只需要简单的指定“firstChild.data”（firstChild指向了那个被&lt;data&gt;节点包含的文本节点，而这个“data”属性则是这个文本节点的实际文本）。</P>
<P style="TEXT-INDENT: 2em">xmlObj.open ('GET', file, true);</P>
<P style="TEXT-INDENT: 2em">xmlObj.send ('');</P>
<P style="TEXT-INDENT: 2em">　　这是我们的ajaxRead函数的最后一个部分。它说了些什么？嗯，xmlObj的这个“open”方法打开了一个到服务器（通过一个指定的协议，这里指定的是“GET”－你可以使用“USE”或者其他别的协议）的连接，去请求一个文件（在我们的例子里，变量“file”被作为一个参数赋给ajaxRead函数－data.xml），而且javascript可以同步（false）或者异步（true，默认值）的处理请求。由于这是异步的Javascript和XML（AJAX），我们将使用默认的异步方式－在这个例子中，使用同步方式将不起作用。</P>
<P style="TEXT-INDENT: 2em">　　这是我们函数中的最后一行，它简单的发送一个空字符串回服务器。如果没有这行，xmlObj的readyState永远不会到4，所以你的页面永远不会更新。这个send方法能够用于作其他事情，但今天我只是用来从服务器上取得数据－并不发送它－所以在这篇文章中我不准备介入任何关于send方法的细节。</P>
<P style="TEXT-INDENT: 2em">function updateObj(obj, data){</P>
<P style="TEXT-INDENT: 2em">&nbsp; document.getElementById(obj).firstChild.data = data;</P>
<P style="TEXT-INDENT: 2em">}</P>
<P style="TEXT-INDENT: 2em">　　现在再稍微解释一下updateObj函数：这个函数使用一个新的值来更新当前页面上任何指定的元素。他的第一个参数，“obj”是当前页面中元素的ID－那个要被更新的对象；它的第二个参数，“data”是用来将那个将被替换值的对象（“obj”）的内容替换掉。一般来说，检验一下并确定当前页面上确实有一个元素的ID是“obj”是比较明智的，但对我们的脚本的这个隔离级别来说校验并不必要。这个函数更新的方式和我们之前从XML文件的“data”节点取得数据的方式类似－它定位它要更新的元素（这时候这个元素的ID代替了它的标签名和在页面中的索引）并设置这个元素的第一个子节点（文本节点）的data属性为新的值。如果你需要使用HTML而不是纯文本来更新一个元素，你也可以使用</P>
<P style="TEXT-INDENT: 2em">document.getElementById(obj).innerHTML = data</P>
<P style="TEXT-INDENT: 2em">　　这就是全部了</P>
<P style="TEXT-INDENT: 2em">　　这个概念很简单，而且代码也不是很难。你能够从某个地方读取一个文件并且不需要重新加载这个web页面。你有足够的灵活性来作各种事情，包括从表单发送数据（不需要重新加载web页面）并且使用一个服务端语言来动态生成XML文件。如果你需要更近一步，记得这个<A href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html">连接</A>是很有用的－哦，还要记得Google是你朋友。在另外的文章中，我将解释你如何配合服务端技术使用AJAX来构造强大的web应用程序。</P>
<P style="TEXT-INDENT: 2em"></P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/374759722008499325997</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/374759722008499325997</guid>
    <pubDate>Fri, 9 May 2008 21:32:59 +0800</pubDate>
    <dcterms:modified>2008-05-09T21:56:54+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[ASP导出Excel数据的四种方法]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/3747597220084991515529</link>
    <description><![CDATA[<div>一、使用OWC 
<P>　　什么是OWC？ </P>
<P>　　OWC是Office Web Compent的缩写，即Microsoft的Office Web组件，它为在Web中绘制图形提供了灵活的同时也是最基本的机制。在一个intranet环境中，如果可以假设客户机上存在特定的浏览器和一些功能强大的软件（如IE5和Office 2000），那么就有能力利用Office Web组件提供一个交互式图形开发环境。这种模式下，客户端工作站将在整个任务中分担很大的比重。 </P>
<P>＜%Option Explicit <BR>Class ExcelGen <BR>Private objSpreadsheet <BR>Private iColOffset </P>
<P>Private iRowOffset <BR>Sub Class_Initialize() <BR>Set objSpreadsheet = Server.CreateObject("OWC.Spreadsheet") <BR>iRowOffset = 2 <BR>iColOffset = 2 <BR>End Sub </P>
<P>Sub Class_Terminate() <BR>Set objSpreadsheet = Nothing 'Clean up <BR>End Sub </P>
<P>Public Property Let ColumnOffset(iColOff) <BR>If iColOff ＞ 0 then <BR>iColOffset = iColOff <BR>Else <BR>iColOffset = 2 <BR>End If <BR>End Property </P>
<P>Public Property Let RowOffset(iRowOff) <BR>If iRowOff ＞ 0 then <BR>iRowOffset = iRowOff <BR>Else <BR>iRowOffset = 2 <BR>End If <BR>End Property Sub GenerateWorksheet(objRS) <BR>'Populates the Excel worksheet based on a Recordset's contents <BR>'Start by displaying the titles <BR>If objRS.EOF then Exit Sub <BR>Dim objField, iCol, iRow <BR>iCol = iColOffset <BR>iRow = iRowOffset <BR>For Each objField in objRS.Fields <BR>objSpreadsheet.Cells(iRow, iCol).Value = objField.Name <BR>objSpreadsheet.Columns(iCol).AutoFitColumns <BR>'设置Excel表里的字体 <BR>objSpreadsheet.Cells(iRow, iCol).Font.Bold = True <BR>objSpreadsheet.Cells(iRow, iCol).Font.Italic = False <BR>objSpreadsheet.Cells(iRow, iCol).Font.Size = 10 <BR>objSpreadsheet.Cells(iRow, iCol).Halignment = 2 '居中 <BR>iCol = iCol + 1 <BR>Next 'objField <BR>'Display all of the data <BR>Do While Not objRS.EOF <BR>iRow = iRow + 1 <BR>iCol = iColOffset <BR>For Each objField in objRS.Fields <BR>If IsNull(objField.Value) then <BR>objSpreadsheet.Cells(iRow, iCol).Value = "" <BR>Else <BR>objSpreadsheet.Cells(iRow, iCol).Value = objField.Value <BR>objSpreadsheet.Columns(iCol).AutoFitColumns <BR>objSpreadsheet.Cells(iRow, iCol).Font.Bold = False <BR>objSpreadsheet.Cells(iRow, iCol).Font.Italic = False <BR>objSpreadsheet.Cells(iRow, iCol).Font.Size = 10 <BR>End If <BR>iCol = iCol + 1 <BR>Next 'objField <BR>objRS.MoveNext <BR>Loop <BR>End Sub Function SaveWorksheet(strFileName) </P>
<P>'Save the worksheet to a specified filename <BR>On Error Resume Next <BR>Call objSpreadsheet.ActiveSheet.Export(strFileName, 0) <BR>SaveWorksheet = (Err.Number = 0) <BR>End Function <BR>End Class </P>
<P>Dim objRS <BR>Set objRS = Server.CreateObject("ADODB.Recordset") <BR>objRS.Open "SELECT * FROM xxxx", "Provider=SQLOLEDB.1;Persist Security </P>
<P>Info=True;User ID=xxxx;Password=xxxx;Initial Catalog=xxxx;Data source=xxxx;" <BR>Dim SaveName <BR>SaveName = Request.Cookies("savename")("name") <BR>Dim objExcel <BR>Dim ExcelPath <BR>ExcelPath = "Excel\" &amp; SaveName &amp; ".xls" <BR>Set objExcel = New ExcelGen <BR>objExcel.RowOffset = 1 <BR>objExcel.ColumnOffset = 1 <BR>objExcel.GenerateWorksheet(objRS) <BR>If objExcel.SaveWorksheet(Server.MapPath(ExcelPath)) then <BR>'Response.Write "＜html＞＜body bgcolor='gainsboro' text='#000000'＞已保存为Excel文件. </P>
<P>＜a href='" &amp; server.URLEncode(ExcelPath) &amp; "'＞下载＜/a＞" <BR>Else <BR>Response.Write "在保存过程中有错误!" <BR>End If <BR>Set objExcel = Nothing <BR>objRS.Close <BR>Set objRS = Nothing <BR>%＞&nbsp; </P>
<P>　　二、用Excel的Application组件在客户端导出到Excel或Word </P>
<P>　　注意：两个函数中的“data“是网页中要导出的table的 id </P>
<P>＜input type="hidden" name="out_word" onclick="vbscript:buildDoc" value="导出到word" class="notPrint"＞ <BR>＜input type="hidden" name="out_excel" onclick="AutomateExcel();" value="导出到excel" class="notPrint"＞&nbsp; </P>
<P>　　导出到Excel代码 </P>
<P>＜SCRIPT LANGUAGE="javascript"＞ <BR>＜!-- <BR>function AutomateExcel() <BR>{ <BR>// Start Excel and get Application object. <BR>var oXL = new ActiveXObject("Excel.Application"); <BR>// Get a new workbook. <BR>var oWB = oXL.Workbooks.Add(); <BR>var oSheet = oWB.ActiveSheet; <BR>var table = document.all.data; <BR>var hang = table.rows.length; </P>
<P>var lie = table.rows(0).cells.length; </P>
<P>// Add table headers going cell by cell. <BR>for (i=0;i＜hang;i++) <BR>{ <BR>for (j=0;j＜lie;j++) <BR>{ <BR>oSheet.Cells(i+1,j+1).value = table.rows(i).cells(j).innerText; <BR>} </P>
<P>} <BR>oXL.Visible = true; <BR>oXL.UserControl = true; <BR>} <BR>//--＞ <BR>＜/SCRIPT＞&nbsp; </P>
<P>　　导出到Word代码 </P>
<P>＜script language="vbscript"＞ <BR>Sub buildDoc <BR>set table = document.all.data <BR>row = table.rows.length <BR>column = table.rows(1).cells.length </P>
<P>Set objWordDoc = CreateObject("Word.Document") </P>
<P>objWordDoc.Application.Documents.Add theTemplate, False <BR>objWordDoc.Application.Visible=True </P>
<P>Dim theArray(20,10000) <BR>for i=0 to row-1 <BR>for j=0 to column-1 <BR>theArray(j+1,i+1) = table.rows(i).cells(j).innerTEXT <BR>next <BR>next <BR>objWordDoc.Application.ActiveDocument.Paragraphs.Add.Range.InsertBefore("综合查询结果集") //显示表格标题 </P>
<P>objWordDoc.Application.ActiveDocument.Paragraphs.Add.Range.InsertBefore("") <BR>Set rngPara = objWordDoc.Application.ActiveDocument.Paragraphs(1).Range <BR>With rngPara <BR>.Bold = True //将标题设为粗体 <BR>.ParagraphFormat.Alignment = 1 //将标题居中 <BR>.Font.Name = "隶书" //设定标题字体 <BR>.Font.Size = 18 //设定标题字体大小 <BR>End With <BR>Set rngCurrent = objWordDoc.Application.ActiveDocument.Paragraphs(3).Range <BR>Set tabCurrent = ObjWordDoc.Application.ActiveDocument.Tables.Add(rngCurrent,row,column) </P>
<P>for i = 1 to column </P>
<P>objWordDoc.Application.ActiveDocument.Tables(1).Rows(1).Cells(i).Range.InsertAfter theArray(i,1) <BR>objWordDoc.Application.ActiveDocument.Tables(1).Rows(1).Cells(i).Range.ParagraphFormat.alignment=1 <BR>next <BR>For i =1 to column <BR>For j = 2 to row <BR>objWordDoc.Application.ActiveDocument.Tables(1).Rows(j).Cells(i).Range.InsertAfter theArray(i,j) <BR>objWordDoc.Application.ActiveDocument.Tables(1).Rows(j).Cells(i).Range.ParagraphFormat.alignment=1 <BR>Next <BR>Next </P>
<P>End Sub <BR>＜/SCRIPT＞&nbsp; </P>
<P>　　三、直接在IE中打开，再存为EXCEL文件 </P>
<P>　　把读出的数据用＜table＞格式，在网页中显示出来，同时，加上下一句即可把EXCEL表在客客户端显示。 </P>
<P>＜%response.ContentType ="application/vnd.ms-excel"%＞&nbsp; </P>
<P>　　注意：显示的页面中，只把＜table＞输出，最好不要输出其他表格以外的信息。 </P>
<P>　　四、导出以半角逗号隔开的csv </P>
<P>　　用fso方法生成文本文件的方法，生成一个扩展名为csv文件。此文件，一行即为数据表的一行。生成数据表字段用半角逗号隔开。（有关fso生成文本文件的方法，在此就不做介绍了） </P>
<P>　　CSV文件介绍 （逗号分隔文件） </P>
<P>　　选择该项系统将创建一个可供下载的CSV 文件； CSV是最通用的一种文件格式，它可以非常容易地被导入各种PC表格及数据库中。 </P>
<P>　　请注意即使选择表格作为输出格式，仍然可以将结果下载CSV文件。在表格输出屏幕的底部，显示有 "CSV 文件"选项，点击它即可下载该文件。 </P>
<P>　　如果您把浏览器配置为将您的电子表格软件与文本（TXT）/逗号分隔文件（CSV） 相关联，当您下载该文件时，该文件将自动打开。下载下来后，如果本地已安装EXCEL，点击此文件，即可自动用EXCEL软件打开此文件。<BR></P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/3747597220084991515529</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/3747597220084991515529</guid>
    <pubDate>Fri, 9 May 2008 21:15:15 +0800</pubDate>
    <dcterms:modified>2008-05-09T21:15:15+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Tar高级应用技巧详细介绍]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/3747597220083239436876</link>
    <description><![CDATA[<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.需要打包应用包war中所以的jsp文件和jar文件，不需要其他的文件.
<P>　　#cd webmod.war</P>
<P>　　#find . -name "*.jsp" -o -name "*.jar" &gt; list</P>
<P>　　#tar -cvzf webmod.tgz -T list</P>
<P>　　这样打包生成的文件就只有jsp和jar格式的文件了</P>
<P>　　2.打包除了doc和help目录下的文件</P>
<P>　　#cd /jboss/service/default/deploy/</P>
<P>　　#tar ——exclude HRWebProject.war/doc ——exclude HRWebProject.war/help ——czvf HRWebProject.tgz HRWebProject.war</P>
<P>　　3.只备份某个目录下面的几个子目录</P>
<P>　　#tar -cf test.tar home/oracle /home/rar</P>
<P>　　4.解压其中的一个文件</P>
<P>　　#tar -xvf test.tar home/rar/rar.txt</P>
<P>　　5.分卷压缩一个目录：如doc</P>
<P>　　在doc目录的上次目录</P>
<P>　　#tar cvf doc | split -b 2m (已2M大小分卷压缩)</P>
<P>　　#cat x* &gt; doc.tar (合成分卷压缩包)</P>
<P>　　或者</P>
<P>　　#tar czvf doc.tar.gz doc/</P>
<P>　　#tar czvfp - doc.tar.gz | split -b 5m</P>
<P>　　#cat x* &gt; doc.tar.gz</P>
<P>　　6.查看压缩包里面的内容:</P>
<P>　　#tar -tf doc.tar</P>
<P>　　#tar -tzvf doc.tar.gz</P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/3747597220083239436876</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/3747597220083239436876</guid>
    <pubDate>Wed, 23 Apr 2008 21:04:36 +0800</pubDate>
    <dcterms:modified>2008-04-23T21:04:36+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[从头开始生成 SELinux]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/37475972200832210534343</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em"><A >简介</A></P>
<P style="TEXT-INDENT: 2em">SELinux 是 2.6 版本的 Linux 内核中提供的强制访问控制 (MAC)系统。对于目前可用的 Linux 安全模块来说，SELinux 是功能最全面，而且测试最充分的，它是在 20 年的 MAC 研究基础上建立的。SELinux 在类型强制服务器中合并了多级安全性或一种可选的多类策略，并采用了基于角色的访问控制概念。有关这些主题的更多信息的链接，请参见本文后面的参考资料 部分。 
</P><P style="TEXT-INDENT: 2em">大部分使用 SELinux 的人使用的都是 SELinux 就绪的发行版，例如 Fedora、Red Hat Enterprise Linux (RHEL)、Debian 或 Gentoo。它们都是在内核中启用 SELinux 的，并且提供一个可定制的安全策略，还提供很多用户层的库和工具，它们都可以使用 SELinux 的功能。 </P>
<P style="TEXT-INDENT: 2em">如果您与很多用户一样希望让系统与以前一样工作，但是要求安全性更好一些，那么可以通过使用一些熟悉的应用程序或者通过使用高级语言编写安全策略来查询和操作 SELinux。然而，在出现问题时 —— 例如内核和用户空间的内容不同步 —— 这些方法就不够了。另外，这些方法还可能会干扰 UNIX&reg; 工程师理解 SELinux 实际上是如何工作的。最后，工程师和安全社区应该明白除了目前发行版所使用的方法之外，还有其他一些方法可以使用 SELinux。 </P>
<P style="TEXT-INDENT: 2em">在本文中，我们将学习如何将一个最初根本不能支持 SELinux 的系统转换成一个强制使用 SELinux 的系统。我们还将学习如何强制采用一些安全访问策略。 </P>
<P style="TEXT-INDENT: 2em">
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><IMG src="http://www.ibm.com/i/v14/rules/blue_rule.gif" border=0>
<P></P>
<P style="TEXT-INDENT: 2em"><IMG src="http://www.ibm.com/i/c.gif" border=0></P></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 align=right>
<TBODY>
<TR align=right>
<TD><IMG src="http://www.ibm.com/i/c.gif" border=0>
<P></P>
<P style="TEXT-INDENT: 2em">
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD vAlign=center><IMG src="http://www.ibm.com/i/v14/icons/u_bold.gif" border=0>
<P></P>
<P style="TEXT-INDENT: 2em"></P></TD>
<TD vAlign=top align=right><A href="http://www.ibm.com/developerworks/cn/linux/l-selinux.html#main">回页首</A></TD></TR></TBODY></TABLE></P></TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em"><A href="http://www.qemu.org/download.html">QEMU 下载页面</A> 下载 QEMU。 
</P><LI>Gentoo，一个基于源代码的 Linux 发行版。Gentoo 对于本练习来说非常理想，因为我们可以在一个运行的系统上安装 Gentoo，而不用管发行版是什么。我们可以在 <A href="http://www.gentoo.org/main/en/where.xml">Gentoo 下载页面</A> 找到最新的版本。 </LI>
<UL></UL>
<P></P>
<P style="TEXT-INDENT: 2em">输入下面的命令，创建一个磁盘映像文件：</P>
<P style="TEXT-INDENT: 2em">qemu-img create -f raw gentoo.img 2G </P>
<P style="TEXT-INDENT: 2em">下一个步骤是启动 QEMU 来对裸磁盘映像文件进行分区，并格式化一个分区。这需要某种 Linux 引导 CD。Knoppix 可以实现这种功能，Gentoo liveCD 也可以实现这种功能。我们可以从下面的地址下载 Gentoo liveCD： </P>
<P style="TEXT-INDENT: 2em">wget ftp://ftp.gtlib.cc.gatech.edu/pub/gentoo/releases/x86/current/installcd/install-x86-minimal-2006.0.iso </P>
<P style="TEXT-INDENT: 2em">为了将来引用方便 —— 少输入几个字符 —— 您可能会希望对这个映像文件重新命名： </P>
<P style="TEXT-INDENT: 2em">mv install-x86-minimal-2005.1.iso gentoo.iso </P>
<P style="TEXT-INDENT: 2em">下面的命令会通知 QEMU 使用 gentoo.iso 作为自己的 CD，它使用 gentoo.img 作为自己的硬盘，并从 CDROM 开始引导： </P>
<P style="TEXT-INDENT: 2em">qemu -hda gentoo.img -cdrom gentoo.iso -boot d </P>
<P style="TEXT-INDENT: 2em">对于默认内核来说，我们只需要按回车键即可。然后输入下面的内容对磁盘映像文件进行分区： </P>
<P style="TEXT-INDENT: 2em"><A href="http://www.ibm.com/developerworks/cn/linux/l-selinux.html#main">回页首</A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em"><A href="http://freshmeat.net/projects/sysvinit/">SysVinit 页面</A> 上的最新版本。我们可以使用后文中 <A href="http://www.ibm.com/developerworks/cn/linux/l-selinux.html#download">下载</A> 一节所给出的链接以 zip 文件的形式来下载补丁 (sysvinit-init.c.diff)；这个补丁可以使用清单 5 中的过程应用于文件 init.c。这个补丁会在系统引导时加载 SELinux 策略。它引入了一个标志 </P>
<P style="TEXT-INDENT: 2em">no_selinux</P>
<P style="TEXT-INDENT: 2em">，如果引导命令包括了 </P>
<P style="TEXT-INDENT: 2em">-p</P>
<P style="TEXT-INDENT: 2em">选项，这个标志就被设置为 1。如果这个标志被设置了，那么就会给出一条警告消息，然后像正常方式一样引导。否则就调用函数 </P>
<P style="TEXT-INDENT: 2em">load_policy()</P>
<P style="TEXT-INDENT: 2em">，这个函数是在这个补丁中定义的。 </P>
<P style="TEXT-INDENT: 2em"><A href="http://www.ibm.com/developerworks/cn/linux/l-selinux.html#download">下载</A> 一节中的 zip 文件）中的程序会根据内核版本号自动构建一个空策略。由于这需要对内核进行分析，因此我们需要向其指出用来为 QEMU 映像编译内核所使用的源代码树。将 mdp.tar.gz 解压到 $ORIG/ 中，并进入结果目录 mdp/。 </P>
<P style="TEXT-INDENT: 2em">输入： </P>
<P style="TEXT-INDENT: 2em">./build.sh -k ../linux-2.6.14. </P>
<P style="TEXT-INDENT: 2em">这会编译程序 mdp，并使用内核目录作为一个参数来运行它。mdp 接着会查看内核所了解的对象类和权限，并创建一个包含数据的 SELinux 策略。所生成的策略有一个 SELinux 用户、一个 SELinux 角色以及一个 SELinux 类型。单个类型可以应用于所有的文件、内核对象和进程，它对自己具有完全的访问权限。后面我们会对这个策略进行定制，但是现在它可以用来进行初始化并使用 SELinux。 </P>
<P style="TEXT-INDENT: 2em">当 build.sh 运行 mdp 时，它会创建几个文件。我们需要 policy.conf 和 file_contexts。第一个是策略的文本表示，后一个是如何标记文件系统的一些指示。 </P>
<P style="TEXT-INDENT: 2em">现在我要将对 policy.conf 的全面学习推迟到后面，因此我们暂时跳过前面 500 到 600 行代码，直接跳到下面这行： </P>
<P style="TEXT-INDENT: 2em">type base_t; </P>
<P style="TEXT-INDENT: 2em">这是该策略中所定义的惟一一个类型。下面这行代码： </P>
<P style="TEXT-INDENT: 2em">role base_r types { base_t }; </P>
<P style="TEXT-INDENT: 2em">定义了一个角色 </P>
<P style="TEXT-INDENT: 2em">base_r</P>
<P style="TEXT-INDENT: 2em">，它与 </P>
<P style="TEXT-INDENT: 2em">base_t</P>
<P style="TEXT-INDENT: 2em">类型关联在一起。这意味着角色 </P>
<P style="TEXT-INDENT: 2em">code_r</P>
<P style="TEXT-INDENT: 2em">中的一个进程可能会在域 </P>
<P style="TEXT-INDENT: 2em">base_t</P>
<P style="TEXT-INDENT: 2em">下面运行。接下来是一些长长的 </P>
<P style="TEXT-INDENT: 2em">allow</P>
<P style="TEXT-INDENT: 2em">语句，每个语句指定了一个对象类，这为 </P>
<P style="TEXT-INDENT: 2em">domain base_t</P>
<P style="TEXT-INDENT: 2em">下面的进程提供了对为该类定义的所有权限来访问 </P>
<P style="TEXT-INDENT: 2em">base_t</P>
<P style="TEXT-INDENT: 2em">类型的对象类的能力。 </P>
<P style="TEXT-INDENT: 2em">接下来，策略会定义一个用户 </P>
<P style="TEXT-INDENT: 2em">user_u</P>
<P style="TEXT-INDENT: 2em">，它与角色 </P>
<P style="TEXT-INDENT: 2em">base_r</P>
<P style="TEXT-INDENT: 2em">建立了关联。作为 SELinux 用户 </P>
<P style="TEXT-INDENT: 2em">user_u</P>
<P style="TEXT-INDENT: 2em">运行的进程可以在 </P>
<P style="TEXT-INDENT: 2em">base_r</P>
<P style="TEXT-INDENT: 2em">角色下面运行。我们早已看到 </P>
<P style="TEXT-INDENT: 2em">base_r</P>
<P style="TEXT-INDENT: 2em">是与 </P>
<P style="TEXT-INDENT: 2em">base_t</P>
<P style="TEXT-INDENT: 2em">类型关联在一起的，因此这两个语句一起使 </P>
<P style="TEXT-INDENT: 2em">user_u:base_r:base_t</P>
<P style="TEXT-INDENT: 2em">成为一个有效的上下文，这意味着允许进程在这个上下文中运行。 </P>
<P style="TEXT-INDENT: 2em">下面几行代码也非常有用。首先： </P>
<P style="TEXT-INDENT: 2em">sid kernel user_u:base_r:base_t </P>
<P style="TEXT-INDENT: 2em">将一个有效上下文分配给系统中的第一个进程。两行之后，您可以看到： </P>
<P style="TEXT-INDENT: 2em">sid unlabeled user_u:base_r:base_t </P>
<P style="TEXT-INDENT: 2em">这会将相同的上下文分配给任何没有标记的文件。 </P>
<P style="TEXT-INDENT: 2em">现在来看一下文件 file_contexts。其中包括两行内容，格式如下： </P>
<P style="TEXT-INDENT: 2em">&lt;regexp&gt; &lt;context&gt; </P>
<P style="TEXT-INDENT: 2em">其中 </P>
<P style="TEXT-INDENT: 2em">regexp</P>
<P style="TEXT-INDENT: 2em">是一个用来对文件名进行比较的正则表达式，</P>
<P style="TEXT-INDENT: 2em">context</P>
<P style="TEXT-INDENT: 2em">是如果这个正则表达式可以匹配就对文件应用的 SELinux 上下文。下面这行代码： </P>
<P style="TEXT-INDENT: 2em">/.* user_u:base_r:base_t </P>
<P style="TEXT-INDENT: 2em">用来将这个上下文分配给系统上的所有文件。 </P>
<P style="TEXT-INDENT: 2em"><A href="http://www.ibm.com/developerworks/cn/linux/l-selinux.html#download">下载</A> 一节中的 zip 文件），我们可以简单地查看系统中所有进程的上下文。这个脚本会简单地打印系统上每个进程的 /proc/&lt;pid&gt;/attr/current 文件的内容。 </P>
<P style="TEXT-INDENT: 2em">SELinux 使用扩展属性来保存文件的内容。Linux 中大部分永久文件系统（ext2、ext3、jfs、xfs 等）都可以支持扩展属性，而 reiserfs 是一个不幸的例外。这些是一些 (name, value) 的数据对，与 inode 关联在一起，其中名字被周期性地划分成名称空间。SELinux 扩展属性在安全性名称空间中，是由 “selinux” 来标识的，因此完整的 xattr 值应该是 “security.selinux”。新的系统调用集允许用户空间查询并设置扩展属性。用来对 xattr 进行查询的系统调用是 </P>
<P style="TEXT-INDENT: 2em">getxattr(2)</P>
<P style="TEXT-INDENT: 2em">。它接受一个文件名、一个属性名、一个缓冲区（xattr 的返回值就保存在这里）以及所提供的缓冲区的大小作为参数。 </P>
<P style="TEXT-INDENT: 2em">showctx.c 文件简单地运行作为命令行提供的所有文件名，并打印 </P>
<P style="TEXT-INDENT: 2em">security.selinux</P>
<P style="TEXT-INDENT: 2em">扩展属性的值，这假设它是存在、可读的，并且具有合适的大小。 </P>
<P style="TEXT-INDENT: 2em">我们可以从后文 <A href="http://www.ibm.com/developerworks/cn/linux/l-selinux.html#download">下载</A> 一节的 zip 文件中获得 showctx.tar.gz 文件，并从中解压出 showctx.c 文件。然后将其放入 QEMU 机器。一种方法是关闭 QEMU 映像，然后执行下面的命令： </P>
<P style="TEXT-INDENT: 2em"></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR vAlign=top>
<TD colSpan=5><IMG src="http://www.ibm.com/i/c.gif" border=0></TD></TR>
<TR>
<TD><IMG src="http://www.ibm.com/i/v14/icons/fw.gif" border=0></TD>
<TD><A href="http://www.ibm.com/developerworks/cn/whichmethod.html">关于下载方法的信息</A></TD>
<TD><IMG src="http://www.ibm.com/i/c.gif" border=0></TD></TR></TBODY></TABLE></P>
<P style="TEXT-INDENT: 2em"><A href="http://www.ibm.com/developerworks/linux/library/l-selinux.html?S_TACT=105AGX52&amp;S_CMP=cn-a-l">英文原文</A></P>
<P style="TEXT-INDENT: 2em">
</P><LI>在 NSA 的 <A href="http://www.nsa.gov/selinux/">Security-Enhanced Linux (SELinux)</A> 主页上学习更多有关 SELinux 的内容。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI><A href="http://www.nsa.gov/selinux/papers/module/t1.html">Implementing SELinux as a Linux Security Module</A> 对 LSM 概要进行了介绍，并详细介绍了 SELinux 的 LSM 实现，以及它与原始内核补丁实现之间的区别。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI><A href="http://selinuxnews.org/wp/">SELinux News</A> 是 SELinux 社区的社区新闻站点。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI>Wikipedia 概要介绍了 <A href="http://en.wikipedia.org/wiki/Mandatory_access_control">强制访问控制</A>、<A href="http://en.wikipedia.org/wiki/Type_enforcement">类型强制</A>、<A href="http://en.wikipedia.org/wiki/Role_based_access_control">基于角色的访问控制</A> 和 <A href="http://en.wikipedia.org/wiki/Multi-Level_Security">多级安全性</A> 的内容。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI>要学习更多有关 Knoppix 的内容，请阅读 “<A href="http://www.ibm.com/developerworks/cn/linux/l-knopp/index.html">Knoppix gives bootable, one-disk Linux</A>”（developerWorks，2003 年 2 月）。
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI>还可以查看 “<A href="http://www.ibm.com/developerworks/cn/linux/l-livecdland.html">在 Linux LiveCD 上分发软件</A>”（developerWorks，2006 年 1 月）中有关其他 LiveCD 文章的链接。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI>“<A href="http://www.ibm.com/developerworks/cn/linux/l-sppriv/index.html">安全编程: 最小化特权</A>”（developerWorks，2004 年 5 月）讨论了用来减少安全漏洞的传统方法和新方法。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI>在 <A href="http://www.ibm.com/developerworks/cn/linux/">developerWorks Linux 专区</A> 中可以找到为 Linux 开发人员准备的更多资源。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI>随时关注 <A href="http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGX52&amp;S_CMP=cn-a-l">developerWorks 技术事件和网络广播</A>。 </LI>
<UL></UL>
<P></P>
<P style="TEXT-INDENT: 2em">获得产品和技术</P>
<P style="TEXT-INDENT: 2em">
</P><UL>
<LI><A href="http://www.qemu.org/">QEMU 主页</A> 上具有 QEMU 的最新文档和下载。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI><A href="http://www.gentoo.org/">gentoo.org</A> 是 Gentoo 新闻和代码的主要资源。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI>从 freshmeat 上下载最新版本的 <A href="http://freshmeat.net/projects/sysvinit/">SysVinit</A>。 
<P></P>
<P style="TEXT-INDENT: 2em"></P></LI></UL>
<P></P>
<P style="TEXT-INDENT: 2em">讨论</P>
<P style="TEXT-INDENT: 2em">
</P><UL>
<LI><A href="http://selinuxnews.org/planet/">Planet SELinux</A> 提供了 SELinux 社区的 blog。 
<P></P>
<P style="TEXT-INDENT: 2em"></P>
</LI><LI>通过参与 <A href="http://www.ibm.com/developerworks/blogs/?S_TACT=105AGX52&amp;S_CMP=cn-a-l">developerWorks blogs</A> 加入 developerWorks 社区。 
<P></P>
<P style="TEXT-INDENT: 2em"></P></LI></UL>
<P></P>
<P style="TEXT-INDENT: 2em"><A >关于作者</A>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD colSpan=3><IMG src="http://www.ibm.com/i/c.gif" border=0></TD></TR>
<TR vAlign=top align=left>
<TD>
<P></P>
<P style="TEXT-INDENT: 2em"></P></TD>
<TD><IMG src="http://www.ibm.com/i/c.gif" border=0></TD>
<TD width="100%">
<P></P>
<P style="TEXT-INDENT: 2em">Serge Hallyn 是 IBM Linux Technology Center 安全团队的一名专职程序员。他从 College of William and Mary 获得了计算机科学博士学位。他实现了几个安全模型 (dte、bsdjail)，并对其他的安全模型 (seclvl) 和 SELinux 贡献了自己的力量。他实现了 DTE 及相应的配置文件和分析工具，并在 Type Enforcement（SELinux 中的主要技术）方面具有丰富的经验。</P></TD></TR></TBODY></TABLE></P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/37475972200832210534343</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/37475972200832210534343</guid>
    <pubDate>Tue, 22 Apr 2008 22:05:34 +0800</pubDate>
    <dcterms:modified>2008-04-22T22:05:34+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Linux版本发展]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/3747597220083221006420</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">Linux内核始于1991年由Linus Torvalds为他的386开发的一个类Minix的操作系统。Linus初始曾想命名为这个系统为Freax，但很幸运的是最后他最后没有那样做。</P>
<P style="TEXT-INDENT: 2em">Linux 1.0的官方版发行于1994年3月，包含了386的官方支持，仅支持单cpu系统。</P>
<P style="TEXT-INDENT: 2em">Linux 1.2发行于1995年3月，它是第一个包含多平台（Alpha，Sparc，Mips等）支持的官方版本。</P>
<P style="TEXT-INDENT: 2em">Linux 2.0发行于1996年6月，包含很多新的平台支持，但是最重要的是，它是第一个支持SMP（对称多处理器）体系的内核版本。</P>
<P style="TEXT-INDENT: 2em">Linux 2.2在1999年1月到来，它带来了SMP系统上性能的极大提升，同时支持更多的硬件。</P>
<P style="TEXT-INDENT: 2em">Linux 2.4于2001年1月发布，它进一步地提升了SMP系统的扩展性，同时它也集成了很多用于支持桌面系统的特性：USB，PC卡（PCMCIA）的支持，内置的即插即用，等等。</P>
<P style="TEXT-INDENT: 2em">Linux 2.6于2003年12月发布，不仅包含了这些特性，同时也是一个无论对相当大的系统还是相当小的系统（PDA等）的支持都有很大提升的"大跨越"。 </P>
<P style="TEXT-INDENT: 2em"></P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/3747597220083221006420</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/3747597220083221006420</guid>
    <pubDate>Tue, 22 Apr 2008 22:00:06 +0800</pubDate>
    <dcterms:modified>2008-04-22T22:00:06+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Linux 文件命令指南]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/37475972200832295042173</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">虽然 GUI 桌面（如 KDE 和 GNOME）能够帮助用户利用 Linux 特性，而无需关于命令行接口的功能知识，但还是经常会需要更多的功能和灵活性。而且，基本熟悉这些命令对于在 shell 脚本中正确地使某些功能自动化仍然是必需的。 <BR><BR>这篇文章是关于 Linux 文件命令的一个“速成教程”，它是为那些刚接触这个操作系统或者只是需要补充这方面知识的用户提供的。它包含了对一些更有用的命令的一个简明的概述以及关于它们的最强大的应用的指导。下面包含的信息 — 结合一些实验 — 将使您能够容易地掌握这些基本的命令。（注意：当涉及到一个与 Oracle 集群文件系统 (OCFS) 结合的内核时，这些命令中的某些命令的行为可能会稍微有所不同。在此情况下，Oracle 提供了一个 OCFS 工具集，该工具集可以为文件命令应用提供一个更好的选择。） <BR><BR>注意，这里包含的所有示例都在 SUSE Linux 8.0 Professional 上进行了测试。虽然没有理由相信它们在其它的系统上将不能工作，但如果出现问题，您应当查看您的文档，以了解可能的变化。 <BR><BR><B>背景概念 </B><BR><BR>在深入研究规范之前，让我们回顾一些基础知识。 <BR><BR><FONT color=#0000cc>文件和命令 </FONT><BR><BR>在 Linux/UNIX 操作系统中，所有事物都被当作文件来处理：硬件设备（包括键盘和终端）、目录、命令本身，当然还有文件。这个奇怪的惯例实际上是 Linux/UNIX 的能力和灵活性的基础。 <BR><BR>大多数（几乎是全部）的命令形式如下： <BR><BR>command [option] [source file(s)] [target file] <BR><BR><FONT color=#0000cc>获取帮助</FONT> <BR><BR>最有用的命令之一是那些提供帮助的命令（特别是对那些学习 Linux 的人而言）。Linux 中的两个重要的信息来源是联机参考手册，或 man 页面和 whatis 工具。您可以用 whatis 命令来访问一个不熟悉的命令的 man 页面。 <BR><BR>$ whatis echo <BR><BR>要了解关于这个命令的更多信息，可以使用： <BR><BR>$ man echo <BR><BR>如果您不知道某个特殊任务所需的命令，您可以用 man -k （也称为 apropos）和一个主题来生成可能的命令。例如： <BR><BR>$ man -k files <BR><BR>一个很有用但常常被忽视的命令可以提供关于使用 man 本身的信息： <BR><BR>$ man man <BR><BR>您可以用 SPACEBAR 来浏览任意的 man 页面；UP ARROW 将向上翻滚文件。.要退出，则输入 q,!，或 CTRL-Z。 <BR><BR><FONT color=#0000cc>用户类别 </FONT><BR><BR>记得那句名言“所有动物一例平等但有些动物比其他动物更加平等”吗？在 Linux 世界中，根用户掌管一切。 <BR><BR>根用户可以以另一个用户名 su （源自 "superuser"）登录。要执行诸如添加一个新用户、打印机或文件系统之类的任务，必须作为根用户登录或者用 su 命令和根用户密码切换到超级用户。系统文件（包括控制初始化过程的系统文件）归根用户所有。虽然可能允许普通用户对它们进行读操作，但出于系统安全性的原因，编辑的权利将留给根用户。 <BR><BR><FONT color=#0000cc>BASH shell </FONT><BR><BR>虽然提供了其它的 shell，但 BASH (Bourne Again Shell) 是 Linux 的默认 shell。它结合了与它同名的 Bourne shell 的特性和 Korn、C 和 TCSH shell 的特性。 <BR><BR>BASH 内置的命令 history 默认记录最后输入的 500 条命令。可以通过在命令提示符下输入 history 来查看它们。要检索某个特定的命令，可以在命令提示符下按 UP ARROW 或 DOWN ARROW，或在历史列表中输入它的编号，并在编号前面加上 "!"，例如： <BR><BR>$ !49 <BR><BR>您还可以通过一条命令在历史列表中离位置最靠前的项目的距离来执行该命令：如果在历史列表中有 53 个事件，$ !-3 将执行事件号 51。 <BR><BR>像 UNIX/Linux 世界的其它 shell 一样，BASH 使用了特殊的环境变量来方便系统管理。例如： <BR><BR>
</P><LI>HOME，用户主目录<BR>
</LI><LI>PATH，Linux 用来搜索您输入的命令的可执行镜像的搜索路径<BR>
</LI><LI>HISTSIZE，系统保存的历史事件的数量 <BR><BR>除了这些保留的关键字之外，您还可以定义您自己的环境变量。例如，Oracle 使用 ORACLE_HOME （还有其它一些变量），要使 Oracle 安装成功完成，必须在您的环境中设置这些变量。 <BR><BR>可以在提示符下临时设置变量： <BR><BR>$HISTSIZE=100 <BR><BR>或者，在 /etc/profile （需要根用户权限）中进行系统范围的永久设置，或在 .profile 中进行局部永久设置。 <BR><BR>可以通过 echo 命令，并用一个 $ 符号来访问一个环境变量的值，进而查看该值。 <BR><BR>$ echo $HOME<BR>/home/bluher <BR><BR>可以用 env 命令来查看当前所有的环境变量。 <BR><BR><FONT color=#0000cc>正则表达式和通配符 </FONT><BR><BR>许多 Linux 命令使用通配符 * 和 ? 来匹配任意数量的字符或分别匹配任意的单个字符；正则模式匹配表达式利用一个句点 (.) 来匹配除“换行符”之外的任意单个字符。这两种情况下都使用方括号 ([ ]) 来匹配除“*”号之外的字符组。不过，* 号在各种情况下有类似但不同的意义：虽然它在 shell 中将匹配一个或更多的字符，但在正则表达式中，它匹配上述字符的零个或更多的实例。一些命令（如 egrep 和 awk）使用了一组更广泛的特殊字符来进行模式匹配。 <BR><STRONG></STRONG></LI>
<P><STRONG>文件处理命令</STRONG> <BR><BR><FONT color=#0000cc>剖析一个文件列表</FONT> <BR><BR>ls 命令用来查看用户有执行权限的任意目录中的文件列表，该命令有许多有趣的选项。例如： <BR><BR></P><CCID_NOBR>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" bgColor=#e6e6e6><PRE><CCID_CODE>$ ls -liah *
22684 -rw-r--r--    1 bluher   users         952 Dec 28 18:43 .profile
19942 -rw-r--r--    1 scalish  users          30 Jan  3 20:00 test2.out
925 -rwxr-xr-x    1 scalish  users         378 Sep  2  2002 test.sh</CCID_CODE></PRE></TD></TR></TBODY></TABLE></P>
<P><BR><BR>上面的列表显示 8 列： <BR><BR></P>
<LI>第 1 列指示文件的 inode，因为我们使用了 -i 选项。剩下的列通过 -l 选项来进行正常显示。<BR>
</LI><LI>第 2 列显示文件类型和文件访问权限。<BR>
</LI><LI>第3 列显示链接数，包括目录。<BR>
</LI><LI>第 4 和第 5 列显示文件的所有者和组所有者。这里，所有者 "bluher" 属于组 "users"。 <BR>
</LI><LI>第 6 列显示文件大小（单位为所显示的单位，而不是默认的字节数，因为我们使用了 -h 选项。<BR>
</LI><LI>第 7 列显示日期（它看起来像是三列），包括月、日和年，以及当天的时间。<BR>
</LI><LI>第 8 列显示文件名。在选项列表中使用 -a 将使列表中包含隐藏文件（如 .profile）的列表。 <BR><BR><FONT color=#0000cc>处理文件</FONT> <BR><BR>可以移动 (mv)、复制 (cp) 或删除 (rm) 文件和目录。明智地使用 -i 选项，以获得确认通常是个不错的主意。 <BR><BR>$ cp -i ls.out ls2.out <BR><BR>cp:overwrite `ls2.out'? <BR><BR>mv 命令允许使用 -b 选项，这将在移动文件之前作一个备份拷贝。rm 和 cp 接受功能强大但却危险的 -r 选项，它将在一个目录和它的文件上递归执行。 <BR><BR>$ rm -ir Test <BR><BR>rm:descend into directory `Test'? y <BR><BR>可以用 mkdir 来创建目录，用 rmdir 来删除目录。不过，因为不能用 rmdir 来删除包含文件的目录，所以使用 rm 加 -r 选项通常要更方便些。 <BR><BR>出于安全的原因，所有的文件都有所有权和保护。文件访问权限（或文件模式）包含之前提到的相同的 10 个字符： <BR><BR>
</LI><LI>第一个字符指示文件类型。最常见的是 - 代表文件，d 代表目录，而 l 代表链接。<BR>
</LI><LI>接下来的 9 个字符是三种用户类别的访问权限：文件所有者（字符 2-4），用户组 (5-7) 和其它 (8-10)，其中 r 表示读权限，w 表示写权限，x 指示一个文件上的执行权限。破折号 - 如果出现在这九个位置的任意一个，则指示这个操作对该类别的用户禁止。 <BR><BR>可以使用 chmod 命令通过字符符号或二进制掩码来设置访问权限。要使用二进制掩码，必须将三个权限组的字符表示转换成二进制格式，然后转换成八进制格式： <BR><BR>用户类别： 所有者 用户组 其它 <BR><BR>字符表示： rwx r-x r-- <BR><BR>二进制表示： 111 101 100 <BR><BR>八进制表示： 7 5 4 <BR><BR>将写权限赋予用户组，您可以使用： <BR><BR>chmod g+w test.sh or chmod 774 test.sh <BR><BR>用 umask 命令，在 /etc/init.dev 文件中进行系统范围内的、或在 .profile 文件中进行的本地的文件权限默认设置。这个命令指示用 777 减去这个数字来获取默认的权限： <BR><BR>$ umask 022 <BR><BR>这将为用户创建的所有新文件生成一个默认的文件权限 755。 <BR><BR>可以用 chown 来修改文件的所有权： <BR><BR>$ chown bluher ls.out <BR><BR>这里，bluher 是新的文件所有者。类似地，组成员资格将按以下方式修改： <BR><BR>$ chgrp devgrp ls.out <BR><BR>这里，devgrp 是新的用户组。 <BR><BR>ls 不提供哪些文件是文本的，哪些文件是二进制的的信息。要了解这个信息，您可以使用 file * 命令。 <BR><BR><FONT color=#0000cc>重命名文件 </FONT><BR><BR>赋予一个文件多个名字的两种流行的方法是利用链接和 alias 命令。Alias 可以用来为一个更长的命令重新起一个更方便的名字： <BR><BR>$ alias ll='ls -l'<BR>$ ll <BR><BR>注意单引号的使用，这使得 BASH 将该项目传递给别名，而不是自己估计它。别名还可用作较长的路径名的缩写： <BR><BR>$ alias jdev9i=/jdev9i/jdev/bin/jdev <BR><BR>关于 alias 和它的反命令 unalias 的更多信息，请查看 BASH 的 man 页面的 "SHELL BUILTIN COMMANDS" 子部分。在最后一个例子中，定义了一个环境变量来实现相同的结果。 <BR><BR>$ export JDEV_HOME=/jdev9i/jdev/bin/jdev<BR>$ echo $JDEV_HOME<BR>/jdev9i/jdev/bin/jdev<BR>$ $JDEV_HOME <BR><BR>链接允许几个文件名引用单个源文件，格式如下： <BR><BR>ln [-s] fileyouwanttolinkto newname <BR><BR>单独的 ln 命令创建到文件的一个硬链接，而使用 -s 选项来创建一个符号链接。简而言之，一个硬链接几乎不能和原始的文件区分开（除了这两个文件的 inode 将相同之外）。符号链接较容易区分，因为它们出现在一个长的文件列表中，并用 -&gt; 来指示源文件，l 指示文件类型。 <BR></LI>
<P style="TEXT-INDENT: 2em"><B>查看和查找文件 </B>
</P><P style="TEXT-INDENT: 2em"><FONT color=#0000cc>文件过滤器</FONT> 
</P><P style="TEXT-INDENT: 2em">用来读取文件内容和在文件内容上执行操作的命令有时被称为 1y滤器。sed 和 awk 命令是两个滤波器的例子，因为在以前的 OTN 文章中有它们详细的讨论，在这里将略过。 
</P><P style="TEXT-INDENT: 2em">诸如 cat、 more 和 less 之类的命令让您能够从命令行查看一个文本文件的内容，而无需调用编辑器。Cat 是 "concatenate" 的缩写，它将默认地在标准输出（显示屏）上显示文件内容。和 cat 一起提供的最有趣的选项之一是 -n 选项，它用编号的输出行来显示文件内容。 
</P><P style="TEXT-INDENT: 2em">$ cat -n test.out<BR>1 This is a test. 
</P><P style="TEXT-INDENT: 2em">因为 cat 一次性输出文件中的所有行，所以您可能更喜欢用 more 和 less，因为它们都一次输出一屏的文件内容。Less 是 more 的一个增强的版本，它允许用来自 vi 文本编辑器的关键命令来增强文件查看。例如，d 向前翻滚、b 向后翻滚 N 行（如果 N 是在 d 或 b 之前指定的）。为 N 输入的值成为随后的 d 命令的默认值。man 页面实用工具使用 less 来显示使用说明的内容。 
</P><P style="TEXT-INDENT: 2em"><FONT color=#0000cc>重定向和管道 </FONT>
</P><P style="TEXT-INDENT: 2em">重定向允许将命令输出重定向到文件中，而不是标准输出，或者类似地，也可重定向输入。重定向的标准符号 &gt; 创建一个新的文件。&gt;&gt; 符号将输出添加到一个现有的文件中： 
</P><P style="TEXT-INDENT: 2em">$ more test2.out<BR>Another test. <BR>$ cat test.out &gt;&gt; test2.out<BR>$ cat test2.out 
</P><P style="TEXT-INDENT: 2em">Another test.<BR>This is a test. 
</P><P style="TEXT-INDENT: 2em">到文件的标准输入可以用 &lt; 符号来重定向： 
</P><P style="TEXT-INDENT: 2em">$ cat &lt; test2.out 
</P><P style="TEXT-INDENT: 2em">错误消息用 2&gt; 和 2&gt;&gt; 来重定向和添加，格式如下： 
</P><P style="TEXT-INDENT: 2em">$ command 2&gt; name_of_error_file 
</P><P style="TEXT-INDENT: 2em">要避免无意地覆盖一个现有的文件，使用 BASH 内置的命令集： 
</P><P style="TEXT-INDENT: 2em">$ set -o noclobber 
</P><P style="TEXT-INDENT: 2em">可以在命令和输出文件之间用 &gt;! 符号来重载这个特性。要关闭这个特性，用 +o 代替 -o。 
</P><P style="TEXT-INDENT: 2em">重定向在一个命令和文件之间、或文件和文件之间工作。重定向语句的一项必须是一个文件。 
</P><P style="TEXT-INDENT: 2em">管道使用 |符号，并且在命令之间工作。例如，您可以用以下方式将一个命令的输出直接发送到打印机上： 
</P><P style="TEXT-INDENT: 2em">$ ls -l * | lpr 
</P><P style="TEXT-INDENT: 2em">可以用以下方式快速地找到历史列表中的一个命令： 
</P><P style="TEXT-INDENT: 2em">$ history | grep cat 
</P><P style="TEXT-INDENT: 2em"><FONT color=#0000cc>更多的滤波器 </FONT>
</P><P style="TEXT-INDENT: 2em">Grep、fgrep 和 egrep 都显示匹配一种模式的行。所有这三个命令都在文件中搜索指定的模式，如果您想不起来一个所需文件的名称，这将非常有用。基本格式是： 
</P><P style="TEXT-INDENT: 2em">grep [options] PATTERN [FILE...] 
</P><P style="TEXT-INDENT: 2em">$ grep -r 'Subject' nsmail 
</P><P style="TEXT-INDENT: 2em">CTRL-Z 将终止上述或其它任何命令。 
</P><P style="TEXT-INDENT: 2em">grep 的最有用的选项可能是 -s。如果您以除根用户之外的任何身份搜索系统文件，那么对于每一个您没有访问权限的文件，都将产生错误消息。这个命令禁止那些消息。 
</P><P style="TEXT-INDENT: 2em">Fgrep（也以 grep -F 调用）只查找固定的字符串，而不是 grep 接收的正则表达式。而 egrep 接收包含更大范围的特殊字符（如 “|”，它指示条件 OR 运算符）的模式。 
</P><P style="TEXT-INDENT: 2em">$ egrep 'Subject|mailto' * 
</P><P style="TEXT-INDENT: 2em"><FONT color=#0000cc>查找文件 </FONT>
</P><P style="TEXT-INDENT: 2em">find 命令的 GNU 版本非常强大、灵活并且比 UNIX 系统上存在的经典版本更具包容性。它对于涉及到目录结构的任务非常有用，包括在文件上查找和执行命令。find 命令的基本格式是： 
</P><P style="TEXT-INDENT: 2em">$ find startdirectory options matchcriteria [actionoptions] 
</P><P style="TEXT-INDENT: 2em">如果您知道文件的名称、或者甚至名称的一部分，但不知道它所处的目录，您可以这么做： 
</P><P style="TEXT-INDENT: 2em">$ find .-name 'test*'<BR>./test<BR>./jdevhome/mywork/EmpWS/EmpBC4J/test 
</P><P style="TEXT-INDENT: 2em">与经典的 UNIX 系统不同，在 Linux 中不需要在末尾添加 -print 操作，因为如果没有指定其它的操作选项，就将假定执行这个操作。在目录起始位置上的一个点 ( . ) 将使 find 在您的工作目录中开始搜索。两个点， ..，在父目录中开始搜索。您可以在任意目录下开始搜索。 
</P><P style="TEXT-INDENT: 2em">注意，您可以使用通配符作为搜索准则的一部分（只要用单引号将整个项目括起来）。 
</P><P style="TEXT-INDENT: 2em">$ find .-name 'test*' -print<BR>./test.out<BR>./test2.out 
</P><P style="TEXT-INDENT: 2em">显示拥有 .out 扩展名的一系列文件： 
</P><P style="TEXT-INDENT: 2em">$ find /home -name '*.out' 
</P><P style="TEXT-INDENT: 2em">不过记住，除非您是作为超级用户运行这个命令，否则您将可能得到许多的 "Permission denied" 错误消息。 
</P><P style="TEXT-INDENT: 2em">最强大的搜索工具之一是和 grep 一起使用的 -exec 操作： 
</P><P style="TEXT-INDENT: 2em">$ find .-name '*.html' -exec grep 'mailto:foo@yahoo.com' {} \; 
</P><P style="TEXT-INDENT: 2em">这里，我们让 find 命令在当前目录中开始执行， .，查找一个 html 文件，*.html，并在当前文件上执行 (-exec) grep 命令，{}。当使用 -exec 操作时，需要一个分号 ;，这是用来在使用 find 命令时执行其它一些操作。需要反斜线 \ 和引号来确保这些项目通过 BASH，以使它们由命令而不是 shell 来进行解释。 
</P><P style="TEXT-INDENT: 2em"><B>立即掌握 Linux 文件命令</B> 
</P><P style="TEXT-INDENT: 2em">在 Linux 中提供了许多有用的命令和利用它们的强大的方法，在此无法一一说明。此外，完成许多任务通常都存在多种方法。 
</P><P style="TEXT-INDENT: 2em">我们已经看到了一些最常用和最有启发意义的 Linux 文件命令。掌握这些基础但却关键的工具将使您的 Linux 学习走上快车道。利用您手头上的 man 页面，和试验的积极性，您现在拥有了足够的信息来开始探索 Linux 文件操作的力量。 </P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/37475972200832295042173</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/37475972200832295042173</guid>
    <pubDate>Tue, 22 Apr 2008 21:50:42 +0800</pubDate>
    <dcterms:modified>2008-04-22T21:50:42+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[关于 Linux系统中关机命令详细解析]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/37475972200832294349897</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">在linux下一些常用的关机/重启命令有shutdown、halt、reboot、及init，它们都可以达到重启系统的目的，但每个命令的内部工作过程是不同的，通过本文的介绍，希望你可以更加灵活的运用各种关机命令。 </P>
<P style="TEXT-INDENT: 2em">1.shutdown </P>
<P style="TEXT-INDENT: 2em">shutdown命令安全地将系统关机。 有些用户会使用直接断掉电源的方式来关闭linux，这是十分危险的。因为linux与windows不同，其后台运行着许多进程，所以强制关机可能会导致进程的数据丢失﹐使系统处于不稳定的状态﹐甚至在有的系统中会损坏硬件设备。而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭。并且login指令会被冻结﹐即新的用户不能再登录。直接关机或者延迟一定的时间才关机都是可能的﹐还可能重启。这是由所有进程〔process〕都会收到系统所送达的信号〔signal决定的。这让像vi之类的程序有时间储存目前正在编辑的文档﹐而像处理邮件〔mail〕和新闻〔news〕的程序则可以正常地离开等等。 </P>
<P style="TEXT-INDENT: 2em">shutdown执行它的工作是送信号〔signal〕给init程序﹐要求它改变runlevel。Runlevel 0被用来停机〔halt〕﹐runlevel 6是用来重新激活〔reboot〕系统﹐而runlevel 1则是被用来让系统进入管理工作可以进行的状态﹔这是预设的﹐假定没有-h也没有-r参数给shutdown。要想了解在停机〔halt〕或者重新开机〔reboot〕过程中做了哪些动作﹐你可以在这个文件/etc/inittab里看到这些runlevels相关的资料。 </P>
<P style="TEXT-INDENT: 2em">shutdown 参数说明: </P>
<P style="TEXT-INDENT: 2em">　　 [-t] 在改变到其它runlevel之前﹐告诉init多久以后关机。 </P>
<P style="TEXT-INDENT: 2em">　　 [-r] 重启计算器。 </P>
<P style="TEXT-INDENT: 2em">　　 [-k] 并不真正关机﹐只是送警告信号给每位登录者〔login〕。 </P>
<P style="TEXT-INDENT: 2em">　　 [-h] 关机后关闭电源〔halt〕。 </P>
<P style="TEXT-INDENT: 2em">　　 [-n] 不用init﹐而是自己来关机。不鼓励使用这个选项﹐而且该选项所产生的后果往往不总是你所预期得到的。 </P>
<P style="TEXT-INDENT: 2em">　　 [-c] cancel current process取消目前正在执行的关机程序。所以这个选项当然没有时间参数﹐但是可以输入一个用来解释的讯息﹐而这信息将会送到每位使用者。 </P>
<P style="TEXT-INDENT: 2em">　　 [-f] 在重启计算器〔reboot〕时忽略fsck。 </P>
<P style="TEXT-INDENT: 2em">[-F] 在重启计算器〔reboot〕时强迫fsck。 </P>
<P style="TEXT-INDENT: 2em">　　 [-time] 设定关机〔shutdown〕前的时间。 　 　　 </P>
<P style="TEXT-INDENT: 2em">2.halt----最简单的关机命令 </P>
<P style="TEXT-INDENT: 2em">其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐文件系统写操作完成后就会停止内核。 </P>
<P style="TEXT-INDENT: 2em">参数说明: </P>
<P style="TEXT-INDENT: 2em">　　 [-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超级块〔superblock〕覆盖修补过的超级块。 </P>
<P style="TEXT-INDENT: 2em">　　 [-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。 </P>
<P style="TEXT-INDENT: 2em">　　 [-d] 不写wtmp纪录〔已包含在选项[-n]中〕。 </P>
<P style="TEXT-INDENT: 2em">　　 [-f] 没有调用shutdown而强制关机或重启。 </P>
<P style="TEXT-INDENT: 2em">　　 [-i] 关机〔或重启〕前﹐关掉所有的网络接口。 </P>
<P style="TEXT-INDENT: 2em">　　 [-p] 该选项为缺省选项。就是关机时调用poweroff。 　 </P>
<P style="TEXT-INDENT: 2em">3.reboot </P>
<P style="TEXT-INDENT: 2em">reboot的工作过程差不多跟halt一样﹐不过它是引发主机重启﹐而halt是关机。它的参数与halt相差不多。 </P>
<P style="TEXT-INDENT: 2em">4.init </P>
<P style="TEXT-INDENT: 2em">init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel)，init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐并且得不到使用shutdown时的信息和等待时间。</P></div>]]></description>
	    <author><![CDATA[黑海]]></author>
	    <comments>http://robinpcy.blog.163.com/blog/static/37475972200832294349897</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://robinpcy.blog.163.com/blog/static/37475972200832294349897</guid>
    <pubDate>Tue, 22 Apr 2008 21:43:49 +0800</pubDate>
    <dcterms:modified>2008-04-22T21:43:49+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Linux 入门时必学60文件处理个命令]]></title>	
    <link>http://robinpcy.blog.163.com/blog/static/37475972200832293931344</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">&nbsp;</P>
<P style="TEXT-INDENT: 2em">Linux系统信息存放在文件里，文件与普通的公务文件类似。每个文件都有自己的名字、内容、存放地址及其它一些管理信息，如文件的用户、文件的大小等。文件可以是一封信、一个通讯录，或者是程序的源语句、程序的数据，甚至可以包括可执行的程序和其它非正文内容。 Linux文件系统具有良好的结构，系统提供了很多文件处理程序。这里主要介绍常用的文件处理命令。 </P>
<P style="TEXT-INDENT: 2em">file </P>
<P style="TEXT-INDENT: 2em">1.作用 </P>
<P style="TEXT-INDENT: 2em">file通过探测文件内容判断文件类型，使用权限是所有用户。 </P>
<P style="TEXT-INDENT: 2em">2.格式 </P>
<P style="TEXT-INDENT: 2em">file [options] 文件名 </P>
<P style="TEXT-INDENT: 2em">3.[options]主要参数 </P>
<P style="TEXT-INDENT: 2em">-v：在标准输出后显示版本信息，并且退出。 </P>
<P style="TEXT-INDENT: 2em">-z：探测压缩过的文件类型。 </P>
<P style="TEXT-INDENT: 2em">-L：允许符合连接。 </P>
<P style="TEXT-INDENT: 2em">-f name：从文件namefile中读取要分析的文件名列表。 </P>
<P style="TEXT-INDENT: 2em">4.简单说明 </P>
<P style="TEXT-INDENT: 2em">使用file命令可以知道某个文件究竟是二进制（ELF格式）的可执行文件, 还是Shell Script文件，或者是其它的什么格式。file能识别的文件类型有目录、Shell脚本、英文文本、二进制可执行文件、C语言源文件、文本文件、DOS的可执行文件。 </P>
<P style="TEXT-INDENT: 2em">5.应用实例 </P>
<P style="TEXT-INDENT: 2em">如果我们看到一个没有后缀的文件grap，可以使用下面命令： </P>
<P style="TEXT-INDENT: 2em">$ file grap </P>
<P style="TEXT-INDENT: 2em">grap： English text </P>
<P style="TEXT-INDENT: 2em">此时系统显示这是一个英文文本文件。需要说明的是，file命令不能探测包括图形、音频、视频等多媒体文件类型。 </P>
<P style="TEXT-INDENT: 2em">mkdir </P>
<P style="TEXT-INDENT: 2em">1.作用 </P>
<P style="TEXT-INDENT: 2em">mkdir命令的作用是建立名称为dirname的子目录，与MS DOS下的md命令类似，它的使用权限是所有用户。 </P>
<P style="TEXT-INDENT: 2em">2.格式 </P>
<P style=