Web服務(wù)移植thttpd在ARM移植_第1頁
Web服務(wù)移植thttpd在ARM移植_第2頁
Web服務(wù)移植thttpd在ARM移植_第3頁
Web服務(wù)移植thttpd在ARM移植_第4頁
Web服務(wù)移植thttpd在ARM移植_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、thttpd在ARM移植1 下載并解壓:下載地址為: HYPERLINK /software/thttpd/ /software/thttpd/ 下載的是最新的2.25b解壓: rootBinnary source# tar -xvzf thttpd-2.25b.tar.gz2 交叉編譯thttpd rootBinnary source # cd thttpd-2.25brootBinnary thttpd-2.25b # CC=/armtools/bin/arm-linux-gcc ./configure -host=arm-linuxrootBinnary thttpd-2.25b # m

2、ake3 安裝與配置3.1 拷貝thttpd二進(jìn)制可執(zhí)行文件到根文件系統(tǒng)/usr/sbin/目錄中 rootBinnary thttpd-2.25b # cp thttpd /fs/usr/sbin/3.2 拷貝thttpd配置文件rootBinnary thttpd-2.25b # cp contrib/redhat-rpm/thttpd.conf /fs/etc/3.3在開發(fā)板上為thttpd創(chuàng)建一個(gè)獨(dú)立的用戶:httpd,并用此用戶創(chuàng)建httpd服務(wù)的根目錄html root/root#adduser httpd(在ARM開發(fā)板上去添加用戶)Changing password for h

3、ttpdEnter the new password (minimum of 5, maximum of 8 characters)Please use a combination of upper and lower case letters and numbers.Enter new password:Bad password: too short.Warning: weak password (continuing).Re-enter new password:passwd786: password for httpd changed by user rootPassword chang

4、ed.root/root#exitprocess -/bin/login (pid 787) exited. Scheduling it for restart.starting pid 790, tty : /bin/login login: httpdPassword:Processing /etc/profile.Set search library path in /etc/profileSet user path in /etc/profileSet PS1 in /etc/profileDonehttpd/home/httpd #mkdir html 3.4 拷貝測試網(wǎng)頁到http

5、d服務(wù)的根目(可選,測試之用): rootBinnary thttpd-2.25b # cp index.html /fs/home/httpd/html/我是動態(tài)編譯所以查看一下需要的動態(tài)庫 rootBinnary thttpd-2.25b # /armtools/bin/arm-linux-readelf -d thttpdDynamic section at offset 0 x12014 contains 21 entries:Tag Type Name/Value0 x00000001 (NEEDED) Shared library: libcrypt.so.10 x00000001

6、 (NEEDED) Shared library: libc.so.60 x0000000c (INIT) 0 x95480 x0000000d (FINI) 0 x165640 x00000004 (HASH) 0 x81280 x00000005 (STRTAB) 0 x8c140 x00000006 (SYMTAB) 0 x84940 x0000000a (STRSZ) 1066 (bytes)0 x0000000b (SYMENT) 16 (bytes)0 x00000015 (DEBUG) 0 x00 x00000003 (PLTGOT) 0 x220e40 x00000002 (P

7、LTRELSZ) 872 (bytes)0 x00000014 (PLTREL) REL0 x00000017 (JMPREL) 0 x91e00 x00000011 (REL) 0 x91a00 x00000012 (RELSZ) 64 (bytes)0 x00000013 (RELENT) 8 (bytes)0 x6ffffffe (VERNEED) 0 x91300 x6fffffff (VERNEEDNUM) 20 x6ffffff0 (VERSYM) 0 x903e0 x00000000 (NULL) 0 x0雖然這里只列出了需要libcrypt 和 libc 這兩個(gè)動態(tài)庫,但是想要

8、運(yùn)行thttpd還需要libnss_files 動態(tài)庫,具體原因如下解釋: rootBinnary thttpd-2.25b$ cp -d /armtools/arm-linux/lib/libnss_files* /fs/lib/你可以在啟動文件里增加thttpd的啟動命令:thttpd -C /etc/thttpd.conf注意只有root有啟動權(quán)限!4、增加對CGI的支持默認(rèn)配置下,thttpd不可以運(yùn)行GCI(特別是動態(tài)編譯的CGI程序)要想使用CGI支持功能,必須更改thttpd.conf的配置:# This section overrides defaultsdir=/home/h

9、ttpd/html#chroot#屏蔽chroot是為了運(yùn)行動態(tài)編譯的CGIuser=httpd# default = nobodylogfile=/var/log/thttpd.logpidfile=/var/run/thttpd.pid# This section _documents_ defaults in effectport=80port參數(shù)用于更改端口號(可不改,若還運(yùn)行了別的WEB服務(wù)器,則需用不同端口)# nosymlink# default = !chroot#symlinks# novhostcgipat=/cgi-bin/*聲明CGI程序的目錄,是以dir為根目錄的路徑

10、# nothrottles# host=# charset=iso-8859-1移植完成,可以測試了(只需在WEB瀏覽器中鍵入開發(fā)板的IP地址即可)。在建立 embedded Linux 系統(tǒng) (root filesystem) 時(shí),鏈接庫相依 (library dependencies)是相當(dāng)重要的目。當(dāng) root filesystem 缺少必要的 library 時(shí),程序當(dāng)然是無法執(zhí)行的,甚致系統(tǒng)也會無法順利啟動。在建構(gòu) embedded Linux 系統(tǒng)時(shí),應(yīng)具備的正確觀念與基本能力。我們把如何找出所需的 library方法整理出 3 項(xiàng)的基本要點(diǎn),依照這 3 種基本款來加入 libra

11、ry 將能解決幾乎所有的 library dependency 問題,這 3 種項(xiàng)基本要點(diǎn)為:(1) 先利用 cross toolchain 的 objdump 觀察NEEDED的項(xiàng)目,加入 library。(2) 再檢查這些 library 是否相依其它 library。(3) 最后要檢視應(yīng)用程序是否使用到需要特定 library 的service。要點(diǎn) 1. 跟 2. 對大家來說沒有什么問題,要點(diǎn) 3. 在我們的 training 課程里,我們以建構(gòu) thttpd (embedded Web server) 的實(shí)際案例來做講解。關(guān)于建構(gòu) thttpd 的案例thttpd 使用到 NSS (

12、Name Service Switch),因此若沒有將 libnss_SERVICE.so 加到 root filesystem,thttpd 在執(zhí)行時(shí)可能會遇到一些奇怪的問題。舉個(gè)例子,當(dāng) thttpd 透過 /etc/passwd 去尋找 (查詢) UNIX user 時(shí),會用到 libnss_files.so (不讀 /etc/shadow),因此會看到以下的錯(cuò)誤訊息:unknown user - root出現(xiàn)這個(gè)錯(cuò)誤的原因是 thttpd 讀不到 root 使用者,要深入探討這個(gè)問題的原理,必須從以下的程序代碼片斷開始探討: 403 /* If were root and were g

13、oing to become another user, get the uid /gid 404 * now. 405 */ 406 if ( getuid() = 0 ) 407 408 pwd = getpwnam( user ); 409 if ( pwd = (struct passwd*) 0 ) 410 411 syslog( LOG_CRIT, unknown user - %.80s, user ); 412 (void) fprintf( stderr, %s: unknown user - %sn, argv0, user ); 413 exit( 1 ); 414 41

14、5 uid = pwd-pw_uid; 416 gid = pwd-pw_gid; 417 這段程序代碼是 thttpd 2.25b 的程序片斷,位于 thttpd.c 的 main() 函數(shù)里。關(guān)于 libnss_SERVICE.so 的議題,Jollen 打算另外再做討論,因?yàn)檫€會與 libc 有關(guān)系。在這里我們由系統(tǒng)建構(gòu)的角度來看這個(gè)問題。因?yàn)槲覀円呀?jīng)習(xí)慣用 objdump 來觀察程序的相依 library,所以當(dāng) objdump 的畫面跟我們預(yù)期的不同時(shí),經(jīng)常一時(shí)無法反應(yīng)過來。例如,以下的訊息是我們所預(yù)期的:# /armtools/bin/arm-linux-objdump -x th

15、ttpd|more.Dynamic Section: NEEDED libcrypt.so.1 NEEDED libnss_files.so.2 NEEDED libc.so.6.但是實(shí)際的訊息卻是像這樣的:#/armtools/bin/arm-linux-objdump -x thttpd|more.Dynamic Section: NEEDED libcrypt.so.1 NEEDED libc.so.6.我們可以用一知半解的思考邏輯來解決問題:thttpd 呼叫到 getpwnam() 函數(shù),此函數(shù)由 libnss_compat 提供,因此解決方案是把 libnss_files.so 加

16、到 root filesystem 里即可。且慢!前面才講到 libnss_compat,怎么后面是把 libnss_files 加到 root filesystem?是這樣的,libnss_compat 用來讀 /etc/shadow,但是現(xiàn)在我們只需要由 /etc/passwd 讀 Unix user,所以使用 libnss_files.so 就行了。執(zhí)行 thttpd 的話,再加上指定 username 的參數(shù)來執(zhí)行:# thttpd -p 80 -d /var/www -u rootlibnss_SERVICE.so 是包含在 glibc 里的鏈接庫,因此可以直接由 cross too

17、lchain 里取得,不必再另行建置。有關(guān) NSS (Name Service Switch) 可參考以下網(wǎng)頁: HYPERLINK /software/libc/manual/html_node/Name-Service-Switch.html /software/libc/manual/html_node/Name-Service-Switch.html HYPERLINK /pub/gnu/Manuals/glibc-2.2.3/html_chapter/libc_28.html /pub/gnu/Manuals/glibc-2.2.3/html_chapter/libc_28.html

18、此處我們以service的角度來探討這個(gè)問題:因?yàn)?thttpd 使用到 Name Service Switch,所以需要加入 libnss_SERVICE.so。另外一種探討的角度是:由 programming 的角度來思考。如果要讀 shadow passwd 的話,是使用 libnss_compat.so。Boa程序的移植1、下載Boa源碼 下載地址: HYPERLINK / / 目前最新發(fā)行版本: 0.94.13 (幾年沒更新版本了) 下載 boa-0.94.13.tar.gz,注意:若從boa上下載的是boa-0.94.13.tar.tar,解壓方式一樣 解壓: rootBinnar

19、y source# tar xzf boa-0.94.13.tar.gz2、生成Makefile文件進(jìn)入boa-0.94.13,直接運(yùn)行src/configure文件 rootBinnary src#CC=/armtools/bin/arm-linux-gcc ./configure#3、修改Makefile文件(注意:必須用cross-2.95.3, 如使用3.4.1、4.1.1等等會出錯(cuò)) #CC = /armtools/bin/arm-linux-gcc #CPP = /armtools/bin/arm-linux-gcc -E4、交叉編譯 rootBinnary src# make5、

20、去除調(diào)試信息,減小體積。(可選) rootBinnary src# /armtools/bin/arm-linux-strip boa6、將編譯好的程序放入根文件系統(tǒng)的/bin目錄下。 rootBinnary src# cp boa /fs/bin/ 二、配置BoaBoa需要在/etc目錄下建立一個(gè)boa目錄,里面放入Boa的主要配置文件boa.conf。在Boa源碼目錄下已有一個(gè)示例boa.conf,可以在其基礎(chǔ)上進(jìn)行修改。 rootBinnary src# cd ./.rootBinnary source# cd ./fs/etc/rootBinnary etc# mkdir boaroo

21、tBinnary etc# chmod 777 boa/rootBinnary etc# cd boarootBinnary boa# kwrite boa.conf1、Group的修改修改 Group nogroup為 Group user(開發(fā)板上有的組)修改 User nobody為 User boa (user組中的一個(gè)成員)根據(jù)你的開發(fā)板的情況設(shè)定。一定要存在的組和用戶。以下是我在開發(fā)板上的操作:rootlocalhost s#adduser -g user boaChanging password for boaEnter the new password (minimum of

22、5, maximum of 8 characters)Please use a combination of upper and lower case letters and numbers.Enter new password:Bad password: too short.Warning: weak password (continuing).Re-enter new password:passwd820: password for boa changed by user rootPassword changed.root#2、ScriptAlias的修改修改 ScriptAlias /c

23、gi-bin/ /usr/lib/cgi-bin/為 ScriptAlias /cgi-bin/ /var/www/cgi-bin/這是在設(shè)置CGI的目錄,你也可以設(shè)置成別的目錄。比如用戶文件夾下的某個(gè)目錄。3、ServerName的設(shè)置修改 #ServerName HYPERLINK .here/ .here為 ServerName HYPERLINK .here/ .here注意:該項(xiàng)默認(rèn)為未打開,執(zhí)行Boa會異常退出,提示“gethostbyname:No such file or directory”,所以必須打開。其它默認(rèn)設(shè)置即可。你也可以設(shè)置為你自己想要的名字。比如我設(shè)置為:Ser

24、verName binnary2410此外,還需要:將mime.types文件復(fù)制/etc目錄下,通??梢詮膌inux主機(jī)的 /etc目錄下直接復(fù)制即可。(以下配置和boa.conf的配置有關(guān))創(chuàng)建日志文件所在目錄/var/log/boa創(chuàng)建HTML文檔的主目錄/var/www創(chuàng)建CGI腳本所在錄 /var/www/cgi-binrootBinnary log# mkdir -m 777 boarootBinnary log# cd .rootBinnary var# mkdir -m 777 wwwrootBinnary var# mkdir -m 777 www/cgi-binrootBi

25、nnary var# cd .rootBinnary rootfs# cp /etc/mime.types etc/三、運(yùn)行Boa開發(fā)板操作:root#boa如果發(fā)現(xiàn)boa沒有運(yùn)行,則可以在開發(fā)板的/var/log/boa/error_log文件中找原因。比如端口已被其他程序占用: root#cat /var/log/boa/error_log20/Feb/2008:21:21:57 +0000 boa.c:194 - unable to bind: Address already in use或是用戶設(shè)置錯(cuò)誤等等,都可以查到。四、功能測試靜態(tài)網(wǎng)頁測試將靜態(tài)網(wǎng)頁存入根文件系統(tǒng)的/var/www

26、目錄下(可以將主機(jī) /usr/share/doc/HTML/目錄下的index.html、homepage.css和img、stylesheet-images目錄復(fù)制到/var/www目錄下)在根文件系統(tǒng)的/var目錄下 rootBinnary var# cp /usr/share/doc/HTML/index.html www/rootBinnary var# cp -r /usr/share/doc/HTML/img www/rootBinnary var# cp /usr/share/doc/HTML/homepage.css www/rootBinnary var# cp -r /us

27、r/share/doc/HTML/stylesheet-images www/直接在瀏覽器中輸入開發(fā)板的IP地址(比如我的是 HYPERLINK 40) ,出現(xiàn)linux的歡迎網(wǎng)頁。靜態(tài)HTML調(diào)試成功。CGI功能測試1、編寫HelloworldCGI.c程序rootBinnary source$ vi helloworldCGI.c(主程序的程序開頭一定要用Tab,而不是空格,不然編譯可能不通過)#include#includeint main(void)printf(Content-type: text/htmlnn);printf(n);printf(CGI Outputn);print

28、f(n);printf(Hello,world.n);printf(n);printf(n);exit(0);2.交叉編譯生成CGI程序 rootBinnary source$ /armtools/bin/arm-linux-gcc -o helloworldCGI helloworldCGI.c將helloworldCGI 拷貝至根文件系統(tǒng)的/var/www/cgi-bin/下rootBinnary source$ cp helloworldCGI ./nfs/rootfs/var/www/cgi-bin/3.測試瀏覽器輸入 HYPERLINK 40/cgi-bin/helloworldCG

29、I 40/cgi-bin/helloworldCGI 網(wǎng)頁出現(xiàn) Hello,world. 調(diào)試成功!附錄資料:從 XML 生成可與 Ajax 共同使用的 JSON時(shí)下,非常流行使用 JavaScript 代碼為數(shù)據(jù)驅(qū)動的 Web 應(yīng)用程序添加互動性。若能將數(shù)據(jù)編碼成 JavaScript Object Notation(JSON)的格式,您就可以更輕松地通過 JavaScript 語言使用它。通過本文,發(fā)掘使用 XSLT V2 從 XML 數(shù)據(jù)生成 JSON 的幾種不同方法。幾年前,許多開發(fā)人員很看好 XML、XSLT、Extensible HTML (XHTML)和其他一些基于標(biāo)記的語言?,F(xiàn)

30、在,Asynchronous JavaScript and XML(AJAX)成了新的熱點(diǎn),人們又將目光轉(zhuǎn)向了使用 JavaScript 代碼的數(shù)據(jù)驅(qū)動的富 Internet 應(yīng)用程序。但是開發(fā)人員是否已經(jīng)消除了 XML 和這一新技術(shù)之間的鴻溝呢?當(dāng)然,您可以在 Web 客戶機(jī)中使用 XML 解析器來讀取數(shù)據(jù),但這種做法會帶來兩個(gè)問題。第一,出于安全方面的原因,XML 數(shù)據(jù)只能從與此頁面相同的那個(gè)域中讀取。這雖然不是什么大的限制因素,但它的確會引起部署方面的問題,還會阻礙 DHTML 小部件的創(chuàng)建。第二,讀取和解析 XML 會非常慢。另一種做法是讓服務(wù)器執(zhí)行 XML 的解析工作,方法是設(shè)置服務(wù)

31、器,使之向?yàn)g覽器發(fā)送以 JavaScript 代碼或時(shí)下流行的 JavaScript Object Notation(JSON)編碼的數(shù)據(jù)。本文將展示如下三種使用 XSLT V2 語言和 Saxon XSLT V2 處理器從 XML 數(shù)據(jù)生成 JSON 的技巧: 簡單編碼 通過函數(shù)調(diào)用加載數(shù)據(jù) 編碼對象 JSON 簡介要學(xué)習(xí)如何將數(shù)據(jù)編碼成 JSON(它只是 JavaScript 的一個(gè)子集),最好的方法是從數(shù)據(jù)開始。清單 1 顯示了書籍列表的一個(gè)示例 XML 數(shù)據(jù)集。清單 1. 基本的圖形化圖書館 Code Generation in Action JackHerrington Mannin

32、g PHP Hacks JackHerrington OReilly Podcasting Hacks JackHerrington OReilly 這個(gè)數(shù)據(jù)集很簡單,只包含三本書,每本書都具有惟一的 ID、書名、作者姓名及出版商的名字。(沒錯(cuò),我只選擇了我自己的書作為數(shù)據(jù)集,但能怨我嗎?這些書實(shí)在是不可多得的節(jié)日和生日禮物。)清單 2 顯示了這些數(shù)據(jù)在 JSON 中的效果。清單 2. JSON 中的示例數(shù)據(jù)集 id: 1, title: Code Generation in Action, first: Jack, last: Herrington, publisher: Manning ,

33、 . 方括號 () 表明這是一個(gè)數(shù)組。大括號 () 則表明這是一個(gè)散列表,該散列表由一組名稱和值對組成。在本例中,我創(chuàng)建了一個(gè)散列表的數(shù)組 用來存儲這類結(jié)構(gòu)式數(shù)據(jù)的一種常見方法。另外一點(diǎn)值得注意的是字符串是通過單引號或雙引號被編碼的。所以,如果我想用單引號編碼 OReilly,我就必須使用反斜杠對它進(jìn)行轉(zhuǎn)義:OReilly。 這讓我編寫的這個(gè) XSLT 樣式表更為有趣了一些。我并未在本例中放上任何日期,但您也可以通過如下兩種方法來編碼日期。第一種方法是將日期作為字符串,該字符串必須在后面被解析。第二種方法是將日期作為一個(gè)對象,比如:publishdate: new Date( 2006, 6,

34、 16, 17, 45, 0 )這段代碼將 publishdate 的值設(shè)置為6/16/2006 5:45:00 p.m.。簡單編碼接下來我將陸續(xù)介紹 JSON 編碼的幾種技巧。第一種也是其中最簡單的一種,此樣式表如 清單 3 所示。清單 3. simple.xsl 樣式表 var g_books = 1, id: ,name: ,first: ,last: ,publisher: ;要理解此樣式表,不妨先來看一下 清單 4 所示的輸出。清單 4. simple.xsl 的輸出var g_books = id: 1,name: Code Generation in Action,first:

35、Jack,last: Herrington,publisher: Manning, id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly, id: 3,name: Podcasting Hacks,first: Jack,last: Herrington,publisher: OReilly;這里,我將名為 g_books 的變量設(shè)置為一個(gè)包含三個(gè)散列表的數(shù)組,每個(gè)散列表包含關(guān)于該書的信息。再回過頭來看看 清單 3,您會發(fā)現(xiàn)第一個(gè)模板匹配 / 路徑,它也是首先應(yīng)用到輸入數(shù)據(jù)集的模板,該模板使用 for-eac

36、h 循環(huán)來遍歷每本書。之后,它使用 標(biāo)記來將文本從該數(shù)據(jù)輸出到 JavaScript 輸出代碼。對于字符串,我使用名為 js:escape() 的定制函數(shù),它在模板之前定義。該函數(shù)使用一個(gè)正則表達(dá)式將一個(gè)單引號標(biāo)記更改為帶有反斜杠的單引號標(biāo)記。最后一個(gè)重要的元素是 標(biāo)記,它告知處理器要輸出的是文本而不是 XML。要檢驗(yàn)此過程是否可以正常工作,我加入了一個(gè) simple .html 文件,該文件引用我在 simple.js 保存的 XSL 樣式表的輸出。這個(gè) HTML 文件如 清單 5 所示。清單 5. simple.html 文件Simple JS loaderdocument.write(

37、Found +g_books.length+ books );.html 文件使用 標(biāo)記簡單地加載已編碼了的 JavaScript 代碼。之后,第二個(gè) 標(biāo)記將數(shù)組的長度寫出到瀏覽器頁面,如 圖 1 所示。圖 1. simple.html 的輸出好了!數(shù)據(jù)文件包含三本書,相應(yīng)的 JavaScript 文件也包含三本書。它真的可以工作!通過函數(shù)加載上述第一個(gè)示例很簡單,而且在大多數(shù)情況下可以發(fā)揮其作用,但它存在一些問題。第一個(gè)問題是對于數(shù)據(jù)何時(shí)被加載沒有任何提示。如果數(shù)據(jù)是像頁面那樣被靜態(tài)加載的,這不成問題。但是如果頁面動態(tài)創(chuàng)建了一個(gè) 標(biāo)記來按需加載數(shù)據(jù),那么就很有必要知道 標(biāo)記是何時(shí)完成的。實(shí)現(xiàn)

38、此功能的最好的方法是讓編碼了的數(shù)據(jù)調(diào)用一個(gè) JavaScript 函數(shù),而不是只設(shè)置數(shù)據(jù)。這個(gè)概念很重要,所以我將花一些時(shí)間來介紹一下為什么您必須要通過動態(tài)生成的 標(biāo)記來加載數(shù)據(jù)。頁面加載后,從服務(wù)器獲得數(shù)據(jù)是 Web 2.0 的核心功能。一種方法是使用 AJAX 機(jī)制通過到服務(wù)器的調(diào)用來加載 XML。然而,出于安全性的原因,AJAX 機(jī)制只限于從單一域獲取數(shù)據(jù)。這在大多數(shù)情況下都沒有問題,但有時(shí),您可能需要 JavaScript 代碼運(yùn)行在他人的頁面上(例如,Google Maps)。在這種情況下從服務(wù)器獲得數(shù)據(jù)的惟一方法是通過動態(tài)加載 標(biāo)記。獲悉 標(biāo)記何時(shí)加載的最好的方法是讓 標(biāo)記返回的腳

39、本調(diào)用函數(shù)而不是簡單地加載數(shù)據(jù)。清單 6 顯示了在函數(shù)調(diào)用中編碼的數(shù)據(jù)。清單 6. Function1.jsAddBooks( id: 1,name: Code Generation in Action,first: Jack,last: Herrington,publisher: Manning, id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly, id: 3,name: Podcasting Hacks,first: Jack,last: Herrington,publisher: OReilly )

40、;清單 7 給出了相應(yīng)的 .html 文件。清單 7. Function1.htmlFunction 1 JS loadervar g_books = ;function AddBooks( books ) g_books = books; drawbooks( g_books );稍后將詳細(xì)介紹 drawbooks 函數(shù)。這里重要的是了解一下頁面如何定義 AddBooks 函數(shù),該函數(shù)隨后會由 function1.js 文件中的腳本調(diào)用。該 AddBooks 函數(shù)負(fù)責(zé)處理數(shù)據(jù)。而且被調(diào)用的 AddBooks 函數(shù)會向頁面指示 標(biāo)記被正確加載,并已加載完成。要?jiǎng)?chuàng)建 function1.js 文

41、件,我只對樣式表稍微做了一點(diǎn)修改,如 清單 8 所示。清單 8. function1.xsl 樣式表AddBooks( 1, id: ,name: ,first: ,last: ,publisher: );這里,我調(diào)用了一個(gè)函數(shù),而不是簡單地設(shè)置一個(gè)變量。這就是我所做的惟一更改?;氐巾撁?,我使用了 drawbooks 函數(shù)來構(gòu)建書的表格,這樣我就能夠確認(rèn)數(shù)據(jù)被正確編碼和正確顯示。此函數(shù)是在 drawbooks.js 內(nèi)定義的,如 清單 9 所示。清單 9. Drawbooks.jsfunction drawbooks( books ) var elTable = document.create

42、Element( table ); for( var b in books ) var elTR = elTable.insertRow( -1 ); var elTD1 = elTR.insertCell( -1 ); elTD1.appendChild( document.createTextNode( booksb.id ) ); var elTD2 = elTR.insertCell( -1 ); elTD2.appendChild( document.createTextNode( ) ); var elTD3 = elTR.insertCell( -1 );

43、 elTD3.appendChild( document.createTextNode( booksb.first ) ); var elTD4 = elTR.insertCell( -1 ); elTD4.appendChild( document.createTextNode( booksb.last ) ); var elTD5 = elTR.insertCell( -1 ); elTD5.appendChild( document.createTextNode( booksb.publisher ) ); document.body.appendChild( elTable );這個(gè)簡

44、單函數(shù)創(chuàng)建了一個(gè)表格節(jié)點(diǎn),然后循環(huán)訪問書的列表并為每本書創(chuàng)建一行,為每個(gè)數(shù)據(jù)元素分配一個(gè)單元格。此頁面上的代碼的結(jié)果如 圖 2 所示。圖 2. function1.html 的結(jié)果現(xiàn)在我就可以查看一下此頁面的輸出并確認(rèn)來自原始 .xml 文件的一切均已被正確轉(zhuǎn)換成 JavaScript 代碼,且數(shù)據(jù)被發(fā)送到 AddData 函數(shù)并被正確添加到頁面。細(xì)化函數(shù)調(diào)用技術(shù)我很喜歡函數(shù)調(diào)用這一技術(shù),但我并不贊同將所有圖書數(shù)據(jù)都放入一個(gè)塊中。另一種方式是為每條記錄采用一個(gè)調(diào)用,如 清單 10 所示。清單 10. Function2.jsAddBook( id: 1,name: Code Generatio

45、n in Action,first: Jack,last: Herrington,publisher: Manning );AddBook( id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly );.對 .html 頁面只需做少許修改,如 清單 11 所示。清單 11. Function2.html.var g_books = ;function AddBook( book ) g_books.push( book ); .這里更改了 XSLT,以使函數(shù)調(diào)用駐留在 for-each 循環(huán)體內(nèi)。清單 12 顯

46、示了更新后的樣式表。清單 12. function2.xsl.AddBook( id: ,name: ,first: ,last: ,publisher: );.對這個(gè)給定示例來說,這種更改看起來有些隨意。但如果原始的 XML 數(shù)據(jù)集有多種數(shù)據(jù)類型,要為每種類型分配一個(gè)單獨(dú)的函數(shù)調(diào)用會使 XSL 和頁面上的 JavaScript 代碼更為簡單、更易于維護(hù)。編碼對象對小的頁面來講,使用 JavaScript 函數(shù)沒有問題。但對于大型項(xiàng)目,就需要使用 JavaScript 語言的一些面向?qū)ο筇匦?。是的,JavaScript 語言可以處理對象而且可以處理得很好。清單 13 顯示了如何創(chuàng)建帶有數(shù)據(jù)的對

47、象。清單 13. Object1.jsg_books.push( new Book( id: 1,name: Code Generation in Action,first: Jack,last: Herrington,publisher: Manning ) );g_books.push( new Book( id: 2,name: PHP Hacks,first: Jack,last: Herrington,publisher: OReilly ) );在本例中,我只簡單地向名為 g_books 的數(shù)組添加了 Book 對象。JavaScript 的對象創(chuàng)建與 Java、C# 或 C+ 編程語言的對象創(chuàng)建十分相似。都是一個(gè) new 操作符后跟一個(gè)類名。參數(shù)放到隨后的括號內(nèi)。在本例中,我傳入了一個(gè)帶值的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論