Luben Park

Java Ben 成长之路

#

RSS知识简介:什么是RSS以及RSS的历史及发展历程

[转]www.rising.com.cn  2005-4-11 16:37:00  信息源:瑞星编译
广告  

    一、什么是RSS?

    也许大家是第一次听到RSS这个概念,那什么是RSS呢?RSS是站点用来和其他站点之间共享内容的一种简易方式(也叫聚合内容),通常被用于新闻和其他按顺序排列的网站,例如Blog。一段项目的介绍可能包含新闻的全部介绍等。或者仅仅是额外的内容或者简短的介绍。这些项目的链接通常都能链接到全部的内容。网络用户可以在客户端借助于支持RSS的新闻聚合工具软件,在不打开网站内容页面的情况下阅读支持RSS输出的网站内容。

    说得更加简单一点,RSS就是一种用来分发和汇集网页内容的XML格式!如果你还是不太明白,没有关系,RSS是什么其实基本就不重要,重要的是RSS可以做什么,下面我们就来了解一下,RSS能给我们带来什么?

    小知识

    BLOG:BLOG是Web Log的简称。在国内,人们通常称它为博客。它是一种作者与读者以日记风格进行交互的中介。在软件社区,人们以博客形式来共享观念与思想变得越来越流行,人们开始以博客的形式互相学习,博客已经成了一个技术交流的场所!如:http://blogs.msdn.com 就是MSDN上的一个blogging。而在国内博客中国也已经越来越有名。http://www.blogchina.com。

    XML:XML是Extensible Markup Language的简写,一种扩展性标识语言。

    二、RSS的历史

    那么RSS究竟代表什么呢?比较普遍的有两种说法,一种是“Rich Site Summary”或“RDF Site Summary”,另一种是“Really Simple Syndication”,之所以有这些分歧,需要从RSS发展的历史说起。

    最初的0.90版本RSS是由Netscape公司设计的,目的是用来建立一个整合了各主要新闻站点内容的门户,但是0.90版本的RSS规范过于复杂,而一个简化的RSS 0.91版本也随着Netscape公司对该项目的放弃而于2000年暂停。

    不久,一家专门从事博客写作软件开发的公司UserLand接手了RSS 0.91版本的发展,并把它作为其博客写作软件的基础功能之一继续开发,逐步推出了0.92、0.93和0.94版本。随着网络博客的流行,RSS作为一种基本的功能也被越来越多的网站和博客软件支持。

    在UserLand公司接手并不断开发RSS的同时,很多的专业人士认识到需要通过一个第三方、非商业的组织,把RSS发展成为一个通用的规范,并进一步标准化。于是2001年一个联合小组在0.90版本RSS的开发原则下,以W3C新一代的语义网技术RDF(Resource Description Framework)为基础,对RSS进行了重新定义,发布RSS1.0,并将RSS定义为“RDF Site Summary”。但是这项工作没有与UserLand公司进行有效的沟通,UserLand公司也不承认RSS 1.0的有效性,并坚持按照自己的设想进一步开发出RSS的后续版本,到2002年9月发布了最新版本RSS 2.0,UserLand公司将RSS定义为“Really Simple Syndication”。

    目前RSS已经分化为RSS 0.9x/2.0和RSS 1.0两个阵营,由于分歧的存在和RSS 0.9x/2.0的广泛应用现状,RSS 1.0还没有成为标准化组织的真正标准。

    三、RSS可以干什么?

    1.订阅BLOG(BLOG上,你可以订阅你工作中所需的技术文章;也可以订阅与你有共同爱好的作者的日志,总之,BLOG上你对什么感兴趣你就可以订什么)

    2.订阅新闻(无论是奇闻怪事、明星消息、体坛风云,只要你想知道的,都可以订阅)

    你再也不用一个网站一个网站,一个网页一个网页去逛了。只要这将你需要的内容订阅在一个RSS阅读器中,这些内容就会自动出现你的阅读器里,你也不必为了一个急切想知道的消息而不断的刷新网页,因为一旦有了更新,RSS阅读器就会自己通知你!

    三、RSS阅读器

    目前,RSS阅读器基本可以分为两类。

    第一类大多数阅读器是运行在计算机桌面上的单机应用程序,通过所订阅网站和博客(blog)中的新闻供应,可自动、定时地更新新闻标题。在该类阅读器中,有Awasu、FeedDemon和RSSReader这三款流行的单机版阅读器都提供免费试用版和付费高级版,另外,新华网在不久前也推出了一款RSS阅读器,它不仅是完全是中文界面,而且目前还是完全的免费软件!(后面我们就将以这款软件为例,为大家介绍怎样来使用RSS阅读器)

    第二类新闻阅读器通常是内嵌于已在计算机中运行的应用程序中。例如,NewsGator内嵌在微软的Outlook中,所订阅的新闻标题位于Outlook的收件箱文件夹中。另外,Pluck内嵌在Internet Explorer浏览器中!

    四、RSS的联合(Syndication)和聚合(Aggregation)

    发布一个RSS文件(一般称为RSS Feed)后,这个RSS Feed中包含的信息就能直接被其他站点调用,而且由于这些数据都是标准的XML格式,所以也能在其他的终端和服务中使用,如PDA、手机、邮件列表等。而且一个网站联盟(比如专门讨论旅游的网站系列)也能通过互相调用彼此的RSS Feed,自动的显示网站联盟中其他站点上的最新信息,这就叫着RSS的联合。这种联合就导致一个站点的内容更新越及时、RSS Feed被调用的越多,该站点的知名度就会越高,从而形成一种良性循环。

    而所谓RSS聚合,就是通过软件工具的方法从网络上搜集各种RSS Feed并在一个界面中提供给读者进行阅读。这些软件可以是在线的WEB工具,如http://my.netscape.com ,http://my.userland.com , http://www.xmltree.com ,http://www.moreover.com ,http://www.oreillynet.com/meerkat 等,也可以是下载到客户端安装的工具

    五、RSS的未来发展

    随着越来越多的站点对RSS的支持,RSS已经成为目前最成功的XML应用。RSS搭建了信息迅速传播的一个技术平台,使得每个人都成为潜在的信息提供者。相信很快我们就会看到大量基于RSS的专业门户、聚合站点和更精确的搜索引擎。

posted @ 2006-02-14 08:46 Ben 阅读(171) | 评论 (0)编辑 收藏

有关webservice的一些介绍和调用方法

     摘要: [转]http://www.54bk.com/user1/8454/archives/2005/26611.html1. 什么是webservice   从表面上看,Web service 就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。这就是说,你能够用编程的方法通过Web来调用这个应用程序。   对Web service 更精确的解释: Web services是建立可...  阅读全文

posted @ 2006-02-13 16:51 Ben 阅读(646) | 评论 (0)编辑 收藏

[转]使用XML的五种场合

使用XML的五种场合
主  题:  使用XML的五种场合[精华] 
作  者:  ChinaOk (蓝蝶[授人以鱼,不如授人以渔]) 
等  级: 
信 誉 值:  103 
所属论坛:  XML/SOAP 
问题点数:  1 
回复次数:  76 
发表时间:  2002-4-8 16:54:32 
在很多研讨会和培训班上我遇到过许多人,他们还不明白为什么要使用XML也不知道如何 
在他们的应用中使用XML。一些来自诸如Gartner公司的报告建议说,商业公司不能再做 
局外人了,不能对XML置之不理。如果你还不清楚XML到底有什么好处的话,你并不是唯 
一的人。 
我决定把与人们和媒体关于XML话题的交谈整理成文,列出XML在应用中的五个最令人喜 
爱的用法。尽管这些并不能包含XML的所有潜在应用,至少是些最重要的领域。 
1、数据交换 
用XML在应用程序和公司之间作数据交换已不是什么秘密了,毫无疑问应被列为第一位。 
那么为什么XML在这个领域里的地位这么重要呢?原因就是XML使用元素和属性来描述数 
据。在数据传送过程中,XML始终保留了诸如父/子关系这样的数据结构。几个应用程序 
可以共享和解析同一个XML文件,不必使用传统的字符串解析或拆解过程。 
相反,普通文件不对每个数据段做描述(除了在头文件中),也不保留数据关系结构。使 
用XML做数据交换可以使应用程序更具有弹性,因为可以用位置(与普通文件一样)或用元 
素名(从数据库)来存取XML数据。 
2、Web服务 
Web服务是最令人激动的革命之一,它让使用不同系统和不同编程语言的人们能够相互交 
流和分享数据。其基础在于Web服务器用XML在系统之间交换数据。交换数据通常用XML标 
记,能使协议取得规范一致,比如在简单对象处理协议(Simple Object Access Protoc 
ol, SOAP)平台上。 
SOAP可以在用不同编程语言构造的对象之间传递消息。这意味着一个C#对象能够与一个 
Java对象进行通讯。这种通讯甚至可以发生在运行于不同操作系统上的对象之间。DCOM 
, CORBA或Java RMI只能在紧密耦合的对象之间传递消息,SOAP则可在松耦合对象之间传 
递消息。 
3、内容管理 
XML只用元素和属性来描述数据,而不提供数据的显示方法。这样,XML就提供了一个优 
秀的方法来标记独立于平台和语言的内容。 
使用象XSLT这样的语言能够轻易地将XML文件转换成各种格式文件,比如HTML, WML, PD 
F, flat file, EDI, 等等。XML具有的能够运行于不同系统平台之间和转换成不同格式 
目标文件的能力使得它成为内容管理应用系统中的优秀选择。  
4、Web集成 
现在有越来越多的设备也支持XML了。使得Web开发商可以在个人电子助理和浏览器之间 
用XML来传递数据。 
为什么将XML文本直接送进这样的设备去呢?这样作的目的是让用户更多地自己掌握数据 
显示方式,更能体验到实践的快乐。常规的客户/服务(C/S)方式为了获得数据排序或更 
换显示格式,必须向服务器发出申请;而XML则可以直接处理数据,不必经过向服务器申 
请查询-返回结果这样的双向“旅程”,同时在设备也不需要配制数据库。 
甚至还可以对设备上的XML文件进行修改并将结果返回给服务器。想像一下,一台具有互 
联网功能并支持XML的电冰箱将会给市场带来多么大的冲击吧。你从此不必早起去取牛奶 
了! 
5、配制 
许多应用都将配制数据存储在各种文件里,比如.INI文件。虽然这样的文件格式已经使 
用多年并一直很好用,但是XML还是以更为优秀的方式为应用程序标记配制数据。使用. 
NET里的类,如XmlDocument和XmlTextReader,将配制数据标记为XML格式,能使其更具 
可读性,并能方便地集成到应用系统中去。使用XML配制文件的应用程序能够方便地处理 
所需数据,不用象其他应用那样要经过重新编译才能修改和维护应用系统。 
如前所述,这里提到的五种使用XML的途径不包括全部场合。

posted @ 2006-01-11 16:40 Ben 阅读(403) | 评论 (0)编辑 收藏

[转贴]使用jsp实现word、excel格式报表打印

使用jsp实现word、excel格式报表打印
转载 (evan 原创)
 

title: 使用JSP实现WORD、EXCEL格式报表打印

author: evan

email: maioto:evan_zhao@hotmail.com

date: 2003-08-21


因为ms word和excel的文档都支持html文本格式,因此可以先用word或excel做好模版,另存为Web页,然后将该html改成jsp,将数据部分动态填入即可,不用很辛苦的调整格式
 
word页面只要在jsp头设置如下指令:
<%@page contentType="application/msword;charset=GBK" %>
 
excel如下:
<%@page contentType="application/vnd.ms-excel;charset=GBK" %>

使用这种方式客户端必须安装有office软件,用户访问时将在ie中直接用word或excel打开该页面。

此方法优势是模板设计、调整方便,无需在服务器端使用复杂的POI或jxl技术,也无需在客户端使用ActiveX控件技术,更安全、方便,轻松实现较好的打印效果。 

microsoft关于服务器端动态创建office文档的资料(asp示例): 
http://support.microsoft.com/default.aspx?scid=KB;en-us;301044&
 
简单示例:

使用word建立一文档,画表格如下:
----------------------------
| 用户名 | 真实姓名 | 性别 |
----------------------------
| guest  | 路人甲   | 男   |
----------------------------
保存为Web页test.htm, 将test.htm改名为test.jsp,修改其中guest、路人甲、男为从数据库动态查询,如下:

<%@ page contentType="application/msword;charset=GBK" %>
<%@ page import="java.sql.*" %>
<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=GB2312">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 9">
<meta name=Originator content="Microsoft Word 9">
<title>用户信息</title>
<!--[if gte mso 9]><xml>
 <o:DocumentProperties>
  <o:Author>evan zhao</o:Author>
  <o:LastAuthor>evan zhao</o:LastAuthor>
  <o:Revision>1</o:Revision>
  <o:TotalTime>1</o:TotalTime>
  <o:Created>2003-08-20T16:26:00Z</o:Created>
  <o:LastSaved>2003-08-20T16:27:00Z</o:LastSaved>
  <o:Pages>1</o:Pages>
  <o:Company>taiping</o:Company>
  <o:Lines>1</o:Lines>
  <o:Paragraphs>1</o:Paragraphs>
  <o:Version>9.2812</o:Version>
 </o:DocumentProperties>
</xml><![endif]--><!--[if gte mso 9]><xml>
 <w:WordDocument>
  <w:PunctuationKerning>
  <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing>
  <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery>
  <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery>
  <w:Compatibility>
   <w:SpaceForUL>
   <w:BalanceSingleByteDoubleByteWidth>
   <w:DoNotLeaveBackslashAlone>
   <w:ULTrailSpace>
   <w:DoNotExpandShiftReturn>
   <w:AdjustLineHeightInTable>
   <w:UseFELayout>
  </w:Compatibility>
 </w:WordDocument>
</xml><![endif]-->
<style>
<!--
 /* Font Definitions */
@font-face
    {font-family:宋体;
    panose-1:2 1 6 0 3 1 1 1 1 1;
    mso-font-alt:SimSun;
    mso-font-charset:134;
    mso-generic-font-family:auto;
    mso-font-pitch:variable;
    mso-font-signature:3 135135232 16 0 262145 0;}
@font-face
    {font-family:"\@宋体";
    panose-1:2 1 6 0 3 1 1 1 1 1;
    mso-font-charset:134;
    mso-generic-font-family:auto;
    mso-font-pitch:variable;
    mso-font-signature:3 135135232 16 0 262145 0;}
 /* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
    {mso-style-parent:"";
    margin:0cm;
    margin-bottom:.0001pt;
    text-align:justify;
    text-justify:inter-ideograph;
    mso-pagination:none;
    font-size:10.5pt;
    mso-bidi-font-size:12.0pt;
    font-family:"Times New Roman";
    mso-fareast-font-family:宋体;
    mso-font-kerning:1.0pt;}
 /* Page Definitions */
@page
    {mso-page-border-surround-header:no;
    mso-page-border-surround-footer:no;}
@page Section1
    {size:595.3pt 841.9pt;
    margin:72.0pt 90.0pt 72.0pt 90.0pt;
    mso-header-margin:42.55pt;
    mso-footer-margin:49.6pt;
    mso-paper-source:0;
    layout-grid:15.6pt;}
div.Section1
    {page:Section1;}
-->
</style>
</head>

<body lang=ZH-CN style='tab-interval:21.0pt;text-justify-trim:punctuation'>

<div class=Section1 style='layout-grid:15.6pt'>


<table border=1 cellspacing=0 cellpadding=0 style='border-collapse:collapse;
 border:none;mso-border-alt:solid windowtext .5pt;mso-padding-alt:0cm 5.4pt 0cm 5.4pt'>
 <tr>
  <td width=189 valign=top style='width:142.0pt;border:solid windowtext .5pt;
  padding:0cm 5.4pt 0cm 5.4pt'>
  <p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
  mso-hansi-font-family:"Times New Roman"'>用户名</span></p>
  </td>
  <td width=189 valign=top style='width:142.05pt;border:solid windowtext .5pt;
  border-left:none;mso-border-left-alt:solid windowtext .5pt;padding:0cm 5.4pt 0cm 5.4pt'>
  <p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
  mso-hansi-font-family:"Times New Roman"'>真实姓名</span></p>
  </td>
  <td width=189 valign=top style='width:142.05pt;border:solid windowtext .5pt;
  border-left:none;mso-border-left-alt:solid windowtext .5pt;padding:0cm 5.4pt 0cm 5.4pt'>
  <p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
  mso-hansi-font-family:"Times New Roman"'>性别</span></p>
  </td>
 </tr>
<%
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 

String url="jdbc:odbc:mydb";

//连接mydb数据库
Connection con=DriverManager.getConnection (url, "", ""); 

try{
  Statement stmt=con.createStatement(); 

  //查询employee表
  ResultSet rs=stmt.executeQuery("select user_name, real_name, gender from employee ");

  while(rs.next()){
%>

 <tr>
  <td width=189 valign=top style='width:142.0pt;border:solid windowtext .5pt;
  border-top:none;mso-border-top-alt:solid windowtext .5pt;padding:0cm 5.4pt 0cm 5.4pt'>
  <p class=MsoNormal><span lang=EN-US><%=rs.getString("user_name")%></span></p>
  </td>
  <td width=189 valign=top style='width:142.05pt;border-top:none;border-left:
  none;border-bottom:solid windowtext .5pt;border-right:solid windowtext .5pt;
  mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt;
  padding:0cm 5.4pt 0cm 5.4pt'>
  <p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
  mso-hansi-font-family:"Times New Roman"'><%=rs.getString("real_name")%></span></p>
  </td>
  <td width=189 valign=top style='width:142.05pt;border-top:none;border-left:
  none;border-bottom:solid windowtext .5pt;border-right:solid windowtext .5pt;
  mso-border-top-alt:solid windowtext .5pt;mso-border-left-alt:solid windowtext .5pt;
  padding:0cm 5.4pt 0cm 5.4pt'>
  <p class=MsoNormal><span style='font-family:宋体;mso-ascii-font-family:"Times New Roman";
  mso-hansi-font-family:"Times New Roman"'><%=rs.getString("gender")%></span></p>
  </td>
 </tr>

<%
  } // end while
  
  rs.close();
  stmt.close();
} finally {
  con.close();
}
%> 
 
</table>

<p class=MsoNormal><span lang=EN-US><![if !supportEmptyParas]> <![endif]><o:p></o:p></span></p>

</div>

</body>

</html>

posted @ 2006-01-05 20:00 Ben 阅读(436) | 评论 (0)编辑 收藏

[转帖]XML轻松学习手册


转载自:http://www.knowsky.com/2991.html

XML轻松学习手册(1)XML快速入门

文章类别:XML教程   发表日期:2003-6-3  星期二  
--------------------------------------------------------------------------------
转自:动态网制作指南 www.knowsky.com
前言

XML越来越热,关于XML的基础教程网络上也随处可见。可是一大堆的概念和术语往往让人望而生畏,很多朋友问我:XML到底有什么用,我们是否需要学习它?我想就我个人学习过程的心得和经验,写一篇比较全面的介绍文章。首先有两点是需要肯定的: 

第一:XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解,等待只会让你失去机会; 

第二:新知识肯定会有很多新概念,尝试理解和接受,您才可能提高。不要害怕和逃避,毕竟我们还年轻。 

提纲

本文共分五大部分。分别是XML快速入门,XML的概念,XML的术语,XML的实现,XML的实例分析。最后附录介绍了XML的相关资源。作者站在普通网页设计人员的角度,用平实生动的语言,向您讲述XML的方方面面,帮助你拨开XML的神秘面纱,快速步入XML的新领域。 

第一章:XML快速入门

一. 什么是XML? 

二. XML是新概念吗? 

三. 使用XML有什么好处? 

四. XML很难学吗? 

五. XML和HTML的区别 

六. XML的严格格式 

七. 关于XML的更多 

一. 什么是XML?

 

这往往是第一个问题,也往往在第一个问题上你就会搞不明白,因为大多的教材上这样回答:

XML是Extensible Markup Language的简写,一种扩展性标识语言。 这是标准的定义。那么什么是标志语言,为什么叫扩展性?已经让人有些糊涂。我想我们这样来理解会好一些:

对HTML你已经非常熟悉了吧,它就是一种标记语言,记得它的全称吗:"Hypertext Markup Language" 超文本标记语言。明白了?同时,HTML里面有很多标签,类似,等,都是在HTML 
4.0里规范和定义,而XML里允许你自己创建这样的标签,所以叫做可扩展性。

这里有几个容易混淆的概念要提醒大家:

1.XML并不是标记语言。它只是用来创造标记语言(比如HTML)的元语言。天,又糊涂了!不要紧,你只要知道这一点:XML和HTML是不一样的,它的用处途比HTML广泛得多,我们将在后面仔细介绍。

2.XML并不是HTML的替代产品。XML不是HTML的升级,它只是HTML的补充,为HTML扩展更多功能。我们仍将在较长的一段时间里继续使用HTML。(但值得注意的是HTML的升级版本XHTML的确正在向适应XML靠拢。)

3.不能用XML来直接写网页。即便是包含了XML数据,依然要转换成HTML格式才能在浏览器上显示。

下面就是一段XML示例文档(例1),用来表示本文的信息:

<myfile>

<title>XML Quick Start</title>

<author>ajie</author>

<email>ajie@aolhoo.com</email>

<date>20010115</date>

</myfile> 

 

注意:

 

1.这段代码仅仅是代码,让你初步感性认识一下XML,并不能实现什么具体应用;

2.其中类似< title>,< author>的语句就是自己创建的标记(tags),它们和HTML标记不一样,例如这里的< title>是文章标题的意思,HTML里的< title>是页面标题。

二. XML是新概念吗? 

不是。XML来源于SGML,一种比HTML更早的标志语言标准。 

关于SGML,我们来简单了解一下,你只需要有个大致概念就可以。 

SGML全称是"Standard Generalized Markup Language"(通用标识语言标准)。看名称就知道:它是标志语言的标准,也就是说所有标志语言都是依照SGML制定的,当然包括HTML。SGML的覆盖面很广,凡是有一定格式的文件都属于SGML,比如报告,乐谱等等,HTML是SGML在网络上最常见的文件格式。因此,人们戏称SGML是HTML的"妈妈"。 


而XML就是SGML的简化版,只不过省略了其中复杂和不常用的部分。(哦,明白了!是HTML第二个"mother",难怪比HTML功能强大呢。),和SGML一样,XML也可以应用在金融,科研等各个领域,我们这里讲的,只是XML在web方面的运用而已。 


到这里,你应该有点明白了:XML是用来创建定义类似HTML的标记语言,然后再用这个标记语言来显示信息。 三. 使用XML有什么好处? 

有了HTML,为什么还需要用XML? 

因为现在网络应用越来越广泛,仅仅靠HTML单一文件类型来处理千变万化的文档和数据已经力不丛心,而且HTML本身语法十分不严密,严重影响网络信息传送和共享。(想想浏览器兼容的问题伤透多少设计师的脑细胞啊。)人们早已经开始探讨用什么方法来满足网络上各种应用的需要。使用SGML是可以的,但SGML太庞大,编程复杂,于是最终选择了"减肥"的SGML---XML作为下一代web运用的数据传输和交互的工具。 


使用XML有什么好处?来看w3c组织(XML标准制定者)的说明: 

XML使得在网络上使用SGML语言更加"简单和直接": 简化了定义文件类型的过程,简化了编程和处理SGML文件的过程,简化了在Web上的传送和共享。 


1.XML可以广泛的运用于web的任何地方; 

2.XML可以满足网络应用的需求; 

3.使用XML将使编程更加简单; 

4.XML便于学习和创建; 

5.XML代码将清晰和便于阅读理解; 

还是抽象了些。让我们在后面的实例教程中慢满体会XML的强大优势吧! 

四. XML很难学吗?

如果你有兴趣学习XML,不禁会问:XML难吗?学习XML需要什么样的基础?

XML非常简单,学习容易。如果你熟悉HTML,你会发现它的文档和HTML非常相似,看同样的示例文档(例1):

?xml version="1.0"?>

<myfile>

<title>XML Quick Start</title>

<author>ajie</author>

<email>ajie@aolhoo.com</email>

<date>20010115</date>

</myfile>

第一行是一个XML声明,表示文档遵循的是XML的1.0 版的规范。

第二行定义了文档里面的第一个元素(element),也称为根元素: < myfile>。这个就类似HTML里的< HTML>开头标记。注意,这个名称是自己随便定义的。

再下面定义了四个子元素:title,author,email,和date。分别说明文章的标题,作者,邮箱和日期。当然,你可以用中文来定义这些标签,看上去更便于理解: 
<?xml version="1.0" encoding="GB2312"?>

<文章>

<标题>XML轻松学习手册</标题>

<作者>ajie</作者>

<信箱>ajie@aolhoo.com</信箱>

<日期>20010115</日期>

</文章>

 

这就是XML的文档,任何掌握HTML的网友都可以直接写出这样简单的XML文档。

另外,学习XML还必须掌握一种页面脚本语言,常见的就是javascript和VB script。因为XML数据是使用script实现HTML中调用和交互的。我们看一个最简单的例子(例2):

1.将下面代码存为myfile.htm


<html>

<head>

<script language="javascript" for="window" event="onload">

var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");

xmlDoc.async="false";

xmlDoc.load("myfile.xml");

nodes = xmlDoc.documentElement.childNodes;

title.innerText = nodesitem(0).text;

author.innerText = nodes.item(1).text;

email.innerText = nodes.item(2).text;

date.innerText = nodes.item(3).text;

</script>

<title>在HTML中调用XML数据</title>

</head>

<body bgcolor="#FFFFFF">

<b>标题: </b>

<span id="title"> </span>

<b>作者: </b>>

<span id="author"></span>

<b>信箱: </b>

<span id="email"></span>

<b>日期:</b>

<span id="date"></span>

</body>

</html>


2.将下面代码存为myfile.xml


<?xml version="1.0" encoding="GB2312"?>

<myfile>

<title>XML轻松学习手册</title>

<author>ajie</author>

<email>ajie@aolhoo.com</email>

<date>20010115</date>

</myfile>


3.将它们放在同一个目录下,用IE5以上版本浏览器打开,可以看到效果。 学习并掌握一种script,你将真正了解到XML无比的强大的功能。

五. XML和HTML的区别 

 

XML和HTML都来自于SGML,它们都含有标记,有着相似的语法,HTML和XML的最大区别在于:HTML是一个定型的标记语言,它用固有的标记来描述,显示网页内容。比如< H1>表示首行标题,有固定的尺寸。相对的,XML则没有固定的标记,XML不能描述网页具体的外观,内容,它只是描述内容的数据形式和结构。 

 


这是一个质的区别:网页将数据和显示混在一起,而XML则将数据和显示分开来。 

 

我们看上面的例子,在myfile.htm中,我们只关心页面的显示方式,我们可以设计不同的界面,用不同的方式来排版页面,但数据是储存在myfile.xml中,不需要任何改变。 

 


(如果你是程序员,你会惊讶的发现,这与模块化面向对象编程的思想极其相似!其实网页何尝不是一种程序呢?) 

 

正是这种区别使得XML在网络应用和信息共享上方便,高效,可扩展。所以我们相信,XML做为一种先进的数据处理方法,将使网络跨越到一个新的境界。

 

六. XML的严格格式

 

吸取HTML松散格式带来的经验教训,XML一开始就坚持实行"良好的格式"。

我们先看HTML的一些语句,这些语句在HTML中随处可见:

1.

sample


2.< b>< i>sample< /b>< /i>


3.< td>sample< /TD>


4.< font color=red>samplar< /font>


在XML文档中,上述几种语句的语法都是错误的。因为:

1.所有的标记都必须要有一个相应的结束标记;

2.所有的XML标记都必须合理嵌套;

3.所有XML标记都区分大小写;

4.所有标记的属性必须用""括起来;

所以上列语句在XML中正确的写法是

1.
sample

2.< b>< i>sample< /i>< /b>
3.< td>sample< /td>
4.< font color="red">samplar< /font>

  另外,XML标记必须遵循下面的命名规则:

1.名字中可以包含字母、数字以及其它字母; 

2.名字不能以数字或"_" (下划线) 开头;

3.名字不能以字母 xml (或 XML 或 Xml ..) 开头;

4.名字中不能包含空格。

在XML文档中任何的差错,都会得到同一个结果:网页不能被显示。各浏览器开发商已经达成协议,对XML实行严格而挑剔的解析,任何细小的错误都会被报告。你可以将上面的myfile.xml修改一下,比如将< email>改为< Email>,然后用IE5直接打开myfile.xml,会得到一个出错信息页面:


<?xml version="1.0" encoding="GB2312"?>

<myfile>

<title>XML轻松学习手册</title>

<author>ajie</author>

<Email>ajie@aolhoo.com</email>

<date>20010115</date>

</myfile> 

七. 关于XML的更多 

好了,到现在你已经知道: 

1.什么是XML; 
2.XML,HTML,SGML之间的关系和区别; 
3.XML的简单应用。 

恭喜你!你已经不再对XML一无所知,并且已经走在了网络技术的前沿。整个学习过程好象并不很难哦:) 

如果你对XML有更多的兴趣,希望进一步了解XML的详细资料和其它的实际运用技术,欢迎继续浏览我们的下一章:XML的概念。
 
XML轻松学习手册(2)XML概念

第二章 XML概念

导言 

经过第一章的快速入门学习,你已经知道了XML是一种能够让你自己创造标识的语言,它可以将数据与格式从网页中分开,它可以储存数据和共享数据的特性使得XML无所不能。如果你希望深入学习XML,系统掌握XML的来龙去脉,那么我们首先还是要回到XML概念的问题上来。XML(Extensible Markup Language),一种扩展性标识语言。"扩展性""标识""语言"。每一个词都明确的点明了XML的重要特点和功能。我们来仔细分析: 

一. 扩展性 
二. 标识 
三. 语言 
四. 结构化 
五. Meta数据 
六. 显示 
七. DOM 

一.扩展性---使用XML,你可以为你的文档建立自己的标记(tags)。 

XML的第一个词是"扩展性",这正是XML强大的功能和弹性的原因。 
在HTML里,有许多固定的标记,我们必须记住然后使用它们,你不能使用HTML规范里没有的标记。而在XML中,你能建立任何你需要的标记。你可以充分发挥你的想象力,给你的文档起一些好记的标记名称。比如,你的文档里包含一些游戏的攻略,你可以建立一个名为<game>的标记,然后在<game>下再根据游戏类别建立<RPG>,<SLG>等标记。只要清晰,易于理解你可以建立任何数量的标记。 

一开始你也许会不适应,因为我们在学习HTML时,有固定的标记可以直接学习和使用;(很多人包括我自己都是边分析别人的代码和标识,边建立自己的网页),而XML却没有任何标记可以学,也很少有文档的标记是一模一样的。我们怎么办?呵呵,没有就自己创建呀。一旦你真正开始写XML文档,你会发现随心所欲的创造新标记也是一份很有趣的事。你可以建立有自己特色的标记,甚至建立你自己的HTML语言。 

扩展性使你有更多的选择和强大的能力,但同时也产生一个问题就是你必须学会规划。你自己要理解自己的文档,知道它由哪几部分组成,相互之间的关系和如何识别它们。 

关于建立标识还需要说明一点,标识是描述数据的类型或特性,比如<width>,年龄<age>,姓名<name>等,而不是数据的内容,比如:<10pxl>,<18>,<张三>,这些都是无用的标记。如果你学过数据库,你可以这样理解,标识就是一种字段名。 

二.标识---使用XML你可以识别文档中的元素。 

XML的第二个词是"标识",这表明了XML的目的是标识文档中的元素。 

不论你是HTML,还是XML,标识的本质在于便于理解,如果没有标识,你的文档在计算机看来只是一个很长的字符串,每个字看起来都一样,没有重点之分。 

通过标识,你的文档才便于阅读和理解,你可以划分段落,列明标题。XML中,你更可以利用其扩展性 来为文档建立更合适的标识。 

不过,有一点要提醒大家注意:标识仅仅是用来识别信息,它本身并不传达信息。例如这样的HTML代码: 

<b>frist step<b> 
这里<b>表示粗体,只用来说明是用粗体来显示"frist step"字符,<b>本身并不包含任何实际的信息,在页面上你看不到<b>,真正传达信息的是"frist step "。 

三.语言---使用XML你要遵循特定的语法来标识你的文档。 

XML第三个词是"语言"。这表明了作为一种语言XML必须遵循一定的规则。虽然XML的扩展性允许你创建新标识,但它仍然必须遵循特定的结构,语法和明确的定义。 

在计算机领域,语言常常表示一?quot;程序语言",用来编程实现一些功能和应用,但不是所有的"语言"都是用来编程的,XML就只是一种用来定义标识和描述信息的语言。 

下面我们来深入了解一下XML应用的其本原理,可能会很枯燥,但是对于整体的理解很重要,你可以先快速过一遍,心里有一个模糊的概念,具体精髓则需要在实践中慢慢领会。

四.结构化---XML促使文档结构化,所有的信息按某种关系排列。 

"结构化"听起来太抽象了,我们这样理解,结构化就是为你的文档建立一个框架,就象写文章先写一个提纲。结构化使你的文档看起来不会杂乱无章,每一部分都紧密联系,形成一个整体。 

结构化有两个原则: 
1.每一部分(每一个元素)都和其他元素有关联。关联的级数就形成了结构。 
2.标识本身的含义与它描述的信息相分离。 

我们来看一个简单的例子帮助理解: 
<?xml version="1.0" encoding="GB2312"?>
<myfile>
<title>XML轻松学习手册</title>
<chapter>XML快速入门
<para>什么是XML</para>
<para>使用XML的好处</para>
</chapter>
<chapter>XML的概念
<para>扩展性</para>
<para>标识</para>
</chapter>
</myfile>
这是本文的XML描述文档,可以看到标识分三级关联,非常清晰: 
<myfile>
<chapter>
<para>
...
</para>
</chapter>
</myfile>
上面这样的文档结构,我们又称之为"文档树",主干是父元素,如<myfile>,分支和页是子元素,如<chapter>和<para>。 

五.Meta数据(Metadata)---专业的XML使用者会使用meta数据来工作。 

在HTML中我们知道可以使用meta标识来定义网页的关键字,简介等,这些标识不会显示在网页中,但可以被搜索引擎搜索到,并影响搜索结果的排列顺序。 

XML对这一原理进行了深化和扩展,用XML,你可以描述你的信息在哪里,你可以通过meta来验证信息,执行搜索,强制显示,或者处理其他的数据。 

下面是一些XML metadata在实际应用中的用途: 

1.可以验证数字签名,使在线商务的提交动作(submission)有效。 
2.可以被方便的建立索引和进行更有效搜索。 
3.可以在不同语言之间传输数据。 

W3C组织正在研究一种名为RDF(Resource Description Framework)的metadata处理方法,可以自动交换信息,W3C宣称,使用RDF配合数字签名,将使网络中存在"真实可信"的电子商务。 

六.显示 

单独用XMl不能显示页面,我们使用格式化技术,比如CSS或者XSL,才能显示XML标记创建的文档。 

我们在前面第一章讲到XML是将数据和格式分离的。XML文档本身不知道如何来显示,必须有辅助文件来帮助实现。(XML取消了所有标识,包括font,color,p等风格样式定义标识,因此XML全部是采用类似DHTML中CSS的方法来定义文档风格样式。),XML中用来设定显示风格样式的文件类型有: 

1.XSL 

XSL全称是Extensible Stylesheet Language(可扩展样式语言), 是将来设计XML文档显示样式的主要文件类型。它本身也是基于XML语言的。使用XSL,你可以灵活的设置文档显示样式,文档将自动适应任何浏览器和PDA(掌上电脑)。 

XSL也可以将XML转化为HTML,那样,老的浏览器也可以浏览XML文档了。 

2.CSS 

CSS大家很熟悉了,全称是Cascading Style Sheets(层叠样式表),是目前用来在浏览器上显示XML文档的主要方法。 

3.Behaviors 

Behaviors现在还没有成为标准。它是微软的IE浏览器特有的功能,用它可以对XML标识设定一些有趣动作。 

七.DOM 

DOM全称是document object model(文档对象模型),DOM是用来干什么的呢?假设把你的文档看成一个单独的对象,DOM就是如何用HTML或者XML对这个对象进行操作和控制的标准。 

面向对象的思想方法已经非常流行了,在编程语言(例如java,js)中,都运用面向对象的编程思想。在XML中,就是要将网页也作为一个对象来操作和控制,我们可以建立自己的对象和模板。与对象进行交流,如何命令对象,就要用到API。API全称Application Programming Interface,它是访问和操作对象的规则。而DOM就是一种详细描述HTML/XML文档对象规则的API。它规定了HTML/XML文档对象的命名协定,程序模型,沟通规则等。在XML文档中,我们可以将每一个标识元素看作一个对象---它有自己的名称和属性。 

XML创建了标识,而DOM的作用就是告诉script如何在浏览器窗口中操作和显示这些标识 

上面我们已经简要的讲述了一些XML的基本原理,我们来看看它们之间的关联以及它们是如何工作的,先看这里一张图:


此主题相关图片如下:

1.XML描述数据类型。例如:"King lear"是一个标题元素; 
2.CSS储存并控制元素的显示样式。例如:标题将被以18pt字体显示 
3.script脚本控制元素如何动作。例如:当一个title元素"out of stock",将被用红色显示。 
4.DOM则为脚本和对象的交流提供一个公共平台,并将结果显示在浏览器窗口。 

如果任何一个部分发生错误,都不会得到正确结果。 

好了,看到这里,我们已经对XML是如何工作的有一个整体的大致的概念。通过这一章的学习,我们可能感觉到XML似乎更偏向数据处理,更方便程序员学习。实际情况也是这样的,XML设计的目的就是用来方便的共享和交互数据的。下一章,我们将系统的了解关于XML的各种术语。欢迎您继续浏览。

XML轻松学习手册(3)XML的术语

第三章 XML的术语

提纲: 


导言 

一.XML文档的有关术语 

二.DTD的有关术语 

导言 


初学XML最令人头疼的就是有一大堆新的术语概念要理解。由于XML本身也是一个崭新的技术,正在不断发展和变化,各组织和各大网络公司(微软,IBM,SUN等)都在不断推出自己的见解和标准,因此新概念漫天飞就不足为奇了。而国内又缺乏权威的机构或组织来对这些术语正式定名,你所看见的有关XML的中文教材大部分是靠作者本身的理解翻译过来的,有些是正确的,有些是错误的,更加妨碍了我们对这些概念的理解和学习。 

你下面将要看到的关于XML术语的解释,也是作者本身的理解和翻译。阿捷是以W3C组织发布的XML1.0标准规范和相关的正式说明文档为根据来讲述。可以确保这些理解是基本正确的,至少不是错误的。你如果想进一步阅读和了解,我在本文的最后部分列明了相关资源的出处和链接,你可以直接访问。好,我们转入正题:

一.XML文档的有关术语

什么是XML文档?知道HTML原代码文件吧,XML文档就是用XML标识写的XML原代码文件。XML文档也是ASCII的纯文本文件,你可以用Notepad创建和修改。XML文档的后缀名为.XML,例如myfile.xml。用IE5.0以上浏览器也可以直接打开.xml文件,但你看到的就是"XML原代码",而不会显示页面内容。你可以将下面代码存为myfile.xml试试:


<?xml version="1.0" encoding="GB2312"?>

<myfile>

<title>XML轻松学习手册</title>

<author>ajie</author>

<email>ajie@aolhoo.com</email>

<date>20010115</date>

</myfile>


XML文档包含三个部分:

1. 一个XML文档声明;

2. 一个关于文档类型的定义;

3. 用XML标识创建的内容。


举例说明:

<?xml version="1.0"?>

<!DOCTYPE filelist SYSTEM "filelist.dtd">

<filelist> 

<myfile>

<title>QUICK START OF XML</title>

<author>ajie</author>

</myfile>

......

</filelist> 

其中第一行<?xml version="1.0"?>就是一个XML文档的声明,第二行说明这个文档是用filelist.dtd来定义文档类型的,第三行以下就是内容主体部分。 
我们来了解XML文档中有关的术语:


1.Element(元素):

元素在HTML我们已经有所了解,它是组成HTML文档的最小单位,在XML中也一样。一个元素由一个标识来定义,包括开始和结束标识以及其中的内容,就象这样:<author>ajie</author> 


唯一不同的就是:在HTML中,标识是固定的,而在XML中,标识需要你自己创建。


2.Tag(标识) 

标识是用来定义元素的。在XML中,标识必须成对出现,将数据包围在中间。标识的名称和元素的名称是一样的。例如这样一个元素:

<author>ajie</author> 

其中<author>就是标识。


3.Attribute(属性): 

什么是属性?看这段HTML代码:<font color="red">word</font>。其中color就是font的属性之一。

属性是对标识进一步的描述和说明,一个标识可以有多个属性,例如font的属性还有size。XML中的属性与HTML中的属性是一样的,每个属性都有它自己的名字和数值,属性是标识的一部分。举例:

<author sex="female">ajie</author>

XML中属性也是自己定义的,我们建议你尽量不使用属性,而将属性改成子元素,例如上面的代码可以改成这样:

<author>ajie

<sex>female</sex>

</author>

原因是属性不易扩充和被程序操作。


4.Declaration(声明) 

在所有XML文档的第一行都有一个XML声明。这个声明表示这个文档是一个XML文档,它遵循的是哪个XML版本的规范。一个XML的声明语句就象这样:

<?xml version="1.0"?> 


5.DTD(文件类型定义) 

DTD是用来定义XML文档中元素,属性以及元素之间关系的。

通过DTD文件可以检测XML文档的结构是否正确。但建立XML文档并不一定需要DTD文件。关于DTD文件的详细说明我们将在下面单独列项。


6.Well-formed XML(良好格式的XML)

一个遵守XML语法规则,并遵守XML规范的文档称之为"良好格式"。如果你所有的标识都严格遵守XML规范,那么你的XML文档就不一定需要DTD文件来定义它。

良好格式的文档必须以一个XML声明开始,例如:

<?xml version="1.0" standalone="yes" encoding="UTF-8"?>

其中你必须说明文档遵守的XML版本,目前是1.0;其次说明文档是"独立的",它不需要DTD文件来验证其中的标识是否有效;第三,要说明文档所使用的语言编码。默认的是UTF-8,如果使用中文,你需要设置为GB2312。

良好格式的XML文档必须有一个根元素,就是紧接着声明后面建立的第一个元素,其它元素都是这个根元素的子元素,属于根元素一组。

良好格式的XML文档的内容书写时必须遵守XML语法。(有关XML语法我们将在下一章仔细讲解)


7.Valid XML(有效的XML)

一个遵守XML语法规则,并遵守相应DTD文件规范的XML文档称为有效的XML文档。注意我们比较"Well-formed XML"和"Valid 
XML",它们最大的差别在于一个完全遵守XML规范,一个则有自己的"文件类型定义(DTD)"。

将XML文档和它的DTD文件进行比较分析,看是否符合DTD规则的过程叫validation(确认)。这样的过程通常我们是通过一个名为parser的软件来处理的。

有效的XML文档也必须以一个XML声明开始,例如:

<?xml version="1.0" standalone="no" encode="UTF-8"?>

和上面例子不同的,在standalone(独立)属性中,这里设置的是"no",因为它必须和相应的DTD一起使用,DTD文件的定义方法如下:

<!DOCTYPE type-of-doc SYSTEM/PUBLIC "dtd-name"> 

其中:

"!DOCTYPE"是指你要定义一个DOCTYPE;

"type-of-doc"是文档类型的名称,由你自己定义,通常于DTD文件名相同;

"SYSTEM/PUBLIC"这两个参数只用其一。SYSTEM是指文档使用的私有DTD文件的网址,而PUBLIC则指文档调用一个公用的DTD文件的网址。

"dtd-name" 就是DTD文件的网址和名称。所有DTD文件的后缀名为".dtd"。

我们还是用上面的例子,应该写成这样:

<?xml version="1.0" standalone="no" encode="UTF-8"?>

<!DOCTYPE filelist SYSTEM "filelist.dtd"> 

二.DTD的有关术语

什么是DTD,我们上面已经简略提到。DTD是一种保证XML文档格式正确的有效方法,可以比较XML文档和DTD文件来看文档是否符合规范,元素和标签使用是否正确。一个DTD文档包含:元素的定义规则,元素间关系的定义规则,元素可使用的属性,可使用的实体或符号规则。

DTD文件也是一个ASCII的文本文件,后缀名为.dtd。例如:myfile.dtd。

为什么要用DTD文件呢?我的理解是它满足了网络共享和数据交互,使用DTD最大的好处在于DTD文件的共享。(就是上文DTD说明语句中的PUBLIC属性)。比如,两个相同行业不同地区的人使用同一个DTD文件来作为文档创建规范,那么他们的数据就很容易交换和共享。网上有其他人想补充数据,也只需要根据公用的DTD规范来建立文档,就立刻可以加入。

目前,已经有数量众多的写好的DTD文件可以利用。针对不同的行业和应用,这些DTD文件已经建立了通用的元素和标签规则。你不需要自己重新创建,只要在他们的基础上加入你需要的新标识。

当然,如果愿意,你可以创建自己的DTD,它可能和你的文档配合的更加完美。建立自己的DTD也是很简单的一件事,一般只需要定义4-5个元素就可以了。

调用DTD文件的方法有两种:

1.直接包含在XML文档内的DTD

你只要在DOCTYPE声明中插入一些特别的说明就可以了,象这样: 

我们有一个XML文档:

<?xml version="1.0" encoding="GB2312"?>

<myfile>

<title>XML轻松学习手册</title>

<author>ajie</author>

</myfile>

我们在第一行后面插入下面代码就可以:

<!DOCTYPE myfile [

<!ELEMENT title (#PCDATA)>

<!ELEMENT author (#PCDATA)>

<!ENTITY copyright "Copyright 2001, Ajie.">

]>
 

2.调用独立的DTD文件

将DTD文档存为.dtd的文件,然后在DOCTYPE声明行中调用,例如,将下面的代码存为myfile.dtd

<!ELEMENT myfile (title, author)>

<!ELEMENT title (#PCDATA)>

<!ELEMENT author (#PCDATA)>
 

然后在XML文档中调用,在第一行后插入:

<!DOCTYPE myfile SYSTEM "myfile.dtd">
 

我们可以看到DTD文档和HTML中js的调用是差不多的,关于DTD文档具体如何写,我们将在下一章和XML文档的语法一起介绍。 


下面我们来了解DTD有关的术语:

1.Schema(规划) 

schema是数据规则的描述。schema做两件事:

a.它定义元素数据类型和元素之间的关系;

b.它定义元素所能包含的内容类型。

DTD就是关于XML文档的一个schema。

2.Document Tree(文档树) 

"文档树"在前面第二章我们已经提到过,它是文档元素分级结构的形象表示。一个文档结构树包含根元素,根元素是最顶级的元素,(就是紧接着XML声明语句后的第一个元素)。看例子:

<?xml version="1.0"?>

<filelist> 

<myfile>

<title>...</title>

<author>...</author>

</myfile>

</filelist>

上面的例子分三级结构排列成"树"状,其中的<filelist>就是根元素。在XML和DTD文件中,第一个定义的都是根元素。
 

3.Parent Element(父元素)/Child Element(子元素)

父元素是指包含有其它元素的元素,被包含的元素称为它的子元素。看上面的"结构树",其中<myfile>是父元素,<title>,<author>是它的子元素,而<myfile>又是<filelist>的子元素。象<title>这样没有包含任何子元素的最后一级元素我们也称之为"页元素"。
4.Parser(解析软件) 

Parser是一种检查XML文档是否遵循DTD规范的工具软件。

XML的parser发展为两类:一种是"非确认类paeser",只检测文档是否遵守XML语法规则,是否用元素标识建立了文档树。另一种是"确认类paeser",它不但检测文档语法,结构树,而且比较解析你使用的元素标识是否遵守了相应DTD文件的规范。

Parser能独立使用,也可以成为编辑软件或浏览器的一部分。在后面的相关资源列表里,我列出了当前比较流行的一些parsers。


  好了,通过第三章的学习,我们已经了解了一些XML和DTD的基本术语,但是我们还不知道怎样来写这些文件,需要遵循什么样的语法,在下一章,将重点介绍有关撰写XML和DTD文档的语法。请继续浏览,谢谢!

XML轻松学习手册(4)XML语法

第四章 XML语法 

提纲: 

一.XML语法规则 
二.元素的语法 
三.注释的语法 
四.CDATA的语法 
五.Namespaces的语法 
六.entity的语法 
七.DTD的语法 

通过前面三章的学习,我们已经对什么是XML,它的实现原理以及相关的术语有所了解。接下来我们就开始学习XML的语法规范,动手写自己的XML文档。

一.XML语法规则

XML的文档和HTML的原代码类似,也是用标识来标识内容。创建XML文档必须遵守下列重要规则:
规则1:必须有XML声明语句
这一点我们在上一章学习时已经提到过。声明是XML文档的第一句,其格式如下:
<?xml version="1.0" standalone="yes/no" encoding="UTF-8"?> 
声明的作用是告诉浏览器或者其它处理程序:这个文档是XML文档。声明语句中的version表示文档遵守的XML规范的版本;standalone表示文档是否附带DTD文件,如果有,参数为no;encoding表示文档所用的语言编码,默认是UTF-8。

规则2:是否有DTD文件
如果文档是一个"有效的XML文档"(见上一章),那么文档一定要有相应DTD文件,并且严格遵守DTD文件制定的规范。DTD文件的声明语句紧跟在XML声明语句后面,格式如下:
<!DOCTYPE type-of-doc SYSTEM/PUBLIC "dtd-name"> 
其中:
"!DOCTYPE"是指你要定义一个DOCTYPE;
"type-of-doc"是文档类型的名称,由你自己定义,通常于DTD文件名相同;
"SYSTEM/PUBLIC"这两个参数只用其一。SYSTEM是指文档使用的私有DTD文件的网址,而PUBLIC则指文档调用一个公用的DTD文件的网址。
"dtd-name" 就是DTD文件的网址和名称。所有DTD文件的后缀名为".dtd"。
我们还是用上面的例子,应该写成这样:
<?xml version="1.0" standalone="no" encode="UTF-8"?>
<!DOCTYPE filelist SYSTEM "filelist.dtd">

规则3:注意你的大小写
在XML文档中,大小写是有区别的。<P>和<p>是不同的标识。注意在写元素时,前后标识大小写要保持一样。例如:<Author>ajie</Author>,写成<Author>ajie</author>是错误的。
你最好养成一种习惯,或者全部大写,或者全部小写,或者大写第一个字母。这样可以减少因为大小写不匹配产生的文档错误。

规则4:给属性值加引号
在HTML代码里面,属性值可以加引号,也可以不加。例如:<font color=red>word</font>和<font color="red">word</font>都可以被浏览器正确解释。
但是在XML中则规定,所有属性值必须加引号(可以是单引号,也可以是双引号),否则将被视为错误。

规则5:所有的标识必须有相应的结束标识
在HTML中,标识可能不是成对出现的,比?lt;br>。而在XML中规定,所有标识必须成对出现,有一个开始标识,就必须有一个结束标识。否则将被视为错误。

规则6:所有的空标识也必须被关闭
空标识就是标识对之间没有内容的标识。比如
,<img>等标识。在XML中,规定所有的标识必须有结束标识,针对这样的空标识,XML中处理的方法是在原标识最后加/,就可以了。例如:

应写为<br />;
<META name="keywords" content="XML, SGML, HTML">应写为<META name="keywords" content="XML, SGML, HTML" />;
<IMG src= "cool.gif">应写为<IMG src= "cool.gif" /> 


第四章 XML语法

二.元素的语法 

元素由一对标识以及其中的内容组成。就象这样:ajie。元素的名称和标识的名称是一样的。标识可以用属性来进一步描述。 

在XML中,没有任何保留字,所以你可以随心所欲的用任何词语来作为元素名称。但是也必须遵守下列规范: 

1.名称中可以包含字母、数字以及其它字母; 

2.名称不能以数字或"_" (下划线)开头; 

3.名称不能以字母 xml(或 XML 或 Xml ..)开头 

4.名称中不能包含空格 

5.名称中间不能包含":"(冒号) 

为了使元素更容易阅读理解和操作,我们还有一些建议: 

1.名称中不要使用"."。因为在很多程序语言中,"."是作为对象的属性,例如:font.color。同样的原因"-"也最好不要用,必须使用的,以"_"代替; 

2.名称尽量简短。 

3.名称的大小写尽量采用同一标准。 

4.名称可以使用非英文字符,比如用中文。但是有些软件可能不支持。(IE5目前是支持中文元素的。) 

另外,补充一点关于属性的说明。在HTML中,属性可以用来定义元素的显示格式,比如:<font color="red">word</font>将把word显示为红色。而在XML中,属性只是对标识的描述,与元素内容的显示无关。例如同样一句:<font color="red">word</font>,并不会将word显示为红色。(那么,有网友会问:如何在XML中将文字显示为红色呢?这就需要使用CSS或者XSL,我们在下面详细讲述。) 

三.注释的语法 

注释是为了便于阅读和理解,在XML文档添加的附加信息,将不会被程序解释或则浏览器显示。 

注释的语法如下: 

<!-- 这里是注释信息 --> 

可以看到,它和HTML中的注释语法是一样的,非常容易。养成良好的注释习惯将使你的文档更加便于维护,共享,看起来也更专业。 

四.CDATA的语法 

CDATA全称character data,翻译为字符数据。我们在写XML文档时,有时需要显示字母,数字和其它的符号本身,比如"<",而在XML中,这些字符已经有特殊的含义,我们怎么办呢?这就需要用到CDATA语法。语法格式如下: 

<![CDATA[这里放置需要显示的字符]]> 

例如: 

<![CDATA[<AUTHOR sex="female">ajie</AUTHOR>]]> 

在页面上显示的内容将是"<AUTHOR sex="female">ajie</AUTHOR>" 


第四章 XML语法

五.Namespaces的语法 

Namespaces翻译为名字空间。名字空间有什么作用呢?当我们在一个XML文档中使用他人的或者多个DTD文件,就会出现这样的矛盾:因为XML中标识都是自己创建的,在不同的DTD文件中,标识名可能相同但表示的含义不同,这就可能引起数据混乱。
比如在一个文档<table>wood table</table>中<table>表示桌子,
而在另一个文档<table>namelist</table>中<table>表示表格。如果我需要同时处理这两个文档,就会发生名字冲突。
了解决这个问题,我们引进了namespaces这个概念。namespaces通过给标识名称加一个网址(URL)定位的方法来区别这些名称相同的标识。 
Namespaces同样需要在XML文档的开头部分声明,声明的语法如下:
<document xmlns:yourname='URL'>
其中yourname是由你定义的namespaces的名称,URL就是名字空间的网址。
假设上面的"桌子<table>"文档来自http://www.zhuozi.com,我们就可以声明为
<document xmlns:zhuozi='http://www.zhuozi.com&#39;> 
然后在后面的标识中使用定义好的名字空间:
<zhuozi:table>wood table</table>
这样就将这两个<table>区分开来。注意的是:设置URL并不是说这个标识真的要到那个网址去读取,仅仅作为一种区别的标志而已。

六.entity的语法

entity翻译为"实体"。它的作用类似word中的"宏",也可以理解为DW中的摸板,你可以预先定义一个entity,然后在一个文档中多次调用,或者在多个文档中调用同一个entity。
entity可以包含字符,文字等等,使用entity的好处在于:1.它可以减少差错,文档中多个相同的部分只需要输入一遍就可以了。2.它提高维护效率。比如你有40个文档都包含copyright的entity,如果需要修改这个copyright,不需要所有的文件都修改,只要改最初定义的entity语句就可以了。
XML定义了两种类型的entity。一种是我们这里说的普通entity,在XML文档中使用;另一种是参数entity,在DTD文件中使用。
entity的定义语法为:
<!DOCTYPE filename [
<!ENTITY entity-name "entity-content"
]
>
例如我要定义一段版权信息:
<!DOCTYPE copyright [
<!ENTITY copyright "Copyright 2001, Ajie. All rights reserved"
]
>
如果我的版权信息内容和他人共享一个XML文件,也可以使用外部调用的方法,语法象这样:
<!DOCTYPE copyright [
<!ENTITY copyright SYSTEM "http://www.sample.com/copyright.xml"> 
]
>
定义好的entity在文档中的引用语法为:&entity-name;
例如,上面定义的版权信息,调用时写作?copyright;
完整的例子如下,你可以copy下来存为copyright.xml观看实例:
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE copyright [
<!ENTITY copyright "Copyright 2001, Ajie. All rights reserved">
]>
<myfile>
<title>XML</title>
<author>ajie</author>
<email>ajie@aolhoo.com</email>
<date>20010115</date>
©right;
</myfile> 


第四章 XML语法

七.DTD的语法 

DTD是"有效XML文档"的必须文件,我们通过DTD文件来定义文档中元素和标识的规则及相互关系。如何建立一个DTD文件呢?让我们一起来学习: 

1.设置元素 

元素是XML文档的基本组成部分。你要在DTD中定义一个元素,然后在XML文档中使用。元素的定义语法为:<!ELEMENT DESCRIPTION (#PCDATA, DEFINITION)*> 

说明: 

"<!ELEMENT" 是元素的声明,说明你要定义的是一个元素; 

声明后面的"DESCRIPTION",是元素的名称; 

"(#PCDATA, DEFINITION)*>"则是该元素的使用规则。规则定义了元素可以包含的内容以及相互的关系。下面的表格概要列出了元素的规则: 

2.元素规则表: 


此主题相关图片如下:

另外,我们还可以为元素定义属性,因为我们不推荐使用属性,在这里就不详细展开了。

 最后,我们来总结一些前四章学习的内容,写一个包含DTD,XML,以及Script的简单实例,便于读者理解:
1.将下面文件存为myfile.dtd
<!ELEMENT myfile (title, author)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>

2.然后建立XML文档myfile.xml:
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE myfile SYSTEM "myfile.dtd">
<myfile>
<title>XML轻松学习手册</title>
<author>ajie</author>
</myfile>

3.建立HTML文档myfile.html
<html>
<head>
<script language="javascript" for="window" event="onload">
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.load("myfile.xml");
nodes = xmlDoc.documentElement.childNodes;
title.innerText = nodes.item(0).text;
author.innerText = nodes.item(1).text;
</script>
<title>在HTML中调用XML数据</title>
</head>
<body bgcolor="#FFFFFF">
<b>标题: </b>
<span id="title"></span><br>
<b>作者: </b>
<span id="author"></span><br>
</body>
</html>

4.用IE5.0以上浏览器打开myfile.html就可以看到效果了。

XML轻松学习手册(5)XML实例解析

第五章:XML实例解析 

提纲: 

一:实例效果 

二:实例解析 
  1.定义新标识。
  2.建立XML文档。
  3.建立相应的HTML文件。 

XML在不同领域有着广泛的应用,比如在科技领域的MathML,无线通信应用的WML,在网络图象方面的SVG等等,我们这里侧重讨论XML在web上的应用。XML在web上应用主要是利用其强大的数据操作能力。一般用XML配合javascript和asp等服务器端程序,可以实现网络上几乎所有的应用需求。 

考虑讲解方便,我们在下面介绍一个简单的实例,不包含服务器端程序。目的在于让您对XML的数据操作能力有一个感性的认识。 

好,我们首先[ 点击这里 ]来看实例的效果。(请用IE5.0以上版本浏览器打开) 

这是一个简单的CD唱片数据检索功能。你通过点击"上一张","下一张"可以看到单张CD的有关信息。这样的效果我们原来用两种方法可以实现: 

1.利用DHTML,将数据隐藏在不同的层中,通过鼠标事件依次显示; 

2.利用后台程序(如ASP,CGI,PHP,JSP等),调用服务器端的数据。 

但是在这个实例中,我们打开页面原代码可以看到,其中没有用DHTML的DIV,也没有表单的action,它完全是用XML来实现的。下面我们来分析它的制作过程:

第一步:定义新标识。
根据实际的CD数据,首先新建一个名为<CD>的标识;其次建立它相关的数据标识,分别是:CD名称<Title>,演唱者<Artist>,出版年代<Year>,国家<Country>,发行公司<Company>和价格<Price>;最后还要建立一个名为目录<CATALOG>的标识。为什么要再建立一个<CATALOG>标识呢?因为在XML文档中规定,必须且只能有一个根元素(标识),我们有多个CD数据,这些数据是并列的关系,所以需要为这些并列的元素建立一个根元素。
以上元素的定义和关系都完全符合XML标准,不需要特别的DTD文件来定义,所以可以省略DTD定义。如果我们想使用DTD来定义,以上过程可以表示为:

<!ELEMENT CATALOG (CD)*>
<!ELEMENT CD (Title,Artist,Year,Country,Company,Price)>
<!ELEMENT Title (#PCDATA)>
<!ELEMENT Artist (#PCDATA)>
<!ELEMENT Year (#PCDATA)>
<!ELEMENT Country (#PCDATA)>
<!ELEMENT Company (#PCDATA)>
<!ELEMENT Price (#PCDATA)>

这段代码表示:元素CATALOG包含多个CD子元素,而子元素CD又依次包含Title, Artist, Year, Country, Company, Price 六个子元素,它们的内容都定义为文本(字符,数字,文本)。(注:具体的语法说明可以看上一章关于DTD的介绍) 

第二步:建立XML文档。

<?xml version="1.0"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tylor</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
<CD>
<TITLE>Greatest Hits</TITLE>
<ARTIST>Dolly Parton</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>RCA</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1982</YEAR>
</CD>
<CD>
<TITLE>Still got the blues</TITLE>
<ARTIST>Gary More</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>Virgin redords</COMPANY>
<PRICE>10.20</PRICE>
<YEAR>1990</YEAR>
</CD>
<CD>
<TITLE>Eros</TITLE>
<ARTIST>Eros Ramazzotti</ARTIST>
<COUNTRY>EU</COUNTRY>
<COMPANY>BMG</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1997</YEAR>
</CD>
</CATALOG> 

上面代码首先用<?xml version="1.0"?>声明语句表明这是一个XML文档,它的格式遵守XML 1.0标准规范。然后是文档内容,结构树非常清晰:
<CATALOG>
<CD>
...... 
</CD>
<CD>
...... 
</CD>

</CATALOG>
一共定义了5组数据。我们将上面的代码存为cd.xml文件,以备调用。 


第三步:建立相应的HTML文件。
1.导入XML数据。
我们知道,目前流行的浏览器中,暂时只有微软的IE5.0以上版本浏览器支持XML。IE是通过在HTML中的object物件来支持插入XML,并通过js的XMLDocument.load()方法来导入数据。我们看代码: <object WIDTH="0" HEIGHT="0"
CLASSID="clsid:550dda30-0541-11d2-9ca9-0060b0ec3d39" ID="xmldso">
</object>

定义一个object,ID名为xmldso。然后在head区用js引入xml数据:

<script for="window" event="onload">
xmldso.XMLDocument.load("cd.xml");
</script>

2.捆绑数据。
然后将用<SPAN>标识来将XML数据绑定在表格中。其中ID,DATASRC,DTATFLD都是<SPAN>的属性。代码如下:

<table>
<tr><td>Title:</td><td><SPAN ID="title" DATASRC=#xmldso DATAFLD="TITLE"></SPAN></td></tr>
<tr><td>Artist:</td><td><SPAN ID="artist" DATASRC=#xmldso DATAFLD="ARTIST"></SPAN></td></tr>
<tr><td>Year:</td><td><SPAN ID="year" DATASRC=#xmldso DATAFLD="YEAR"></SPAN></td></tr>
<tr><td>Country:</td><td><SPAN ID="country" DATASRC=#xmldso DATAFLD="COUNTRY"></SPAN></td></tr>
<tr><td>Company:</td><td><SPAN ID="company" DATASRC=#xmldso DATAFLD="COMPANY"></SPAN></td></tr>
<tr><td>Price:</td><td><SPAN ID="price" DATASRC=#xmldso DATAFLD="PRICE"></SPAN></td></tr>
</table>

3.动作操作。
最后,为数据提供浏览按钮:
<INPUT TYPE=button value="上一张CD" onCLICK="moveprevious()">
<INPUT TYPE=button value="下一张CD" onCLICK="movenext()">

并利用js来完成两个鼠标点击功能:movenext()和moveprevious()。在head区加入如下代码:

<script language="javascript">
function movenext()
{
if (xmldso.recordset.absoluteposition < xmldso.recordset.recordcount)
{
xmldso.recordset.movenext();
}
}
function moveprevious()
{
if (xmldso.recordset.absoluteposition > 1)
{
xmldso.recordset.moveprevious();
}
}
</script>

好,我们先看HTML文件的全部原代码:

<html>
<head>

<script for="window" event="onload">
xmldso.XMLDocument.load("cd.xml");
</script>

<script language="javascript">
function movenext()
{
if (xmldso.recordset.absoluteposition < xmldso.recordset.recordcount)
{
xmldso.recordset.movenext();
}
}
function moveprevious()
{
if (xmldso.recordset.absoluteposition > 1)
{
xmldso.recordset.moveprevious();
}
}
</script>

<TITLE>CD Navigate</TITLE>
</head>

<body>
<p>
<object WIDTH="0" HEIGHT="0"
CLASSID="clsid:550dda30-0541-11d2-9ca9-0060b0ec3d39" ID="xmldso">
</object>

<table>
<tr><td>Title:</td><td><SPAN ID="title" DATASRC=#xmldso DATAFLD="TITLE"></SPAN></td></tr>
<tr><td>Artist:</td><td><SPAN ID="artist" DATASRC=#xmldso DATAFLD="ARTIST"></SPAN></td></tr>
<tr><td>Year:</td><td><SPAN ID="year" DATASRC=#xmldso DATAFLD="YEAR"></SPAN></td></tr>
<tr><td>Country:</td><td><SPAN ID="country" DATASRC=#xmldso DATAFLD="COUNTRY"></SPAN></td></tr>
<tr><td>Company:</td><td><SPAN ID="company" DATASRC=#xmldso DATAFLD="COMPANY"></SPAN></td></tr>
<tr><td>Price:</td><td><SPAN ID="price" DATASRC=#xmldso DATAFLD="PRICE"></SPAN></td></tr>
</table>

<p>
<INPUT TYPE=button value="上一张CD" onCLICK="moveprevious()">
<INPUT TYPE=button value="下一张CD" onCLICK="movenext()">
</p>

</body>
</html>

将以上代码存为cd.htm文件,于第二步的cd.xml文件放在一起。打开cd.htm文件,你就看见和上面实例一样的效果了。

好,到今天为止,我们已经学习了关于XML的不少知识,我们来总结一下前面五个章节,分别是XML快速入门,XML的概念原理,XML的术语,XML的语法和本章的实例解析。到这里,教程部分就结束了。在写作过程中,阿捷尽最大努力将有关XML概念讲得通俗易懂,尽量把自己的理解告诉给大家,但因为本人学习XML时间也不长,对整个XML的技术把握还不够系统和深入,所以难免有疏漏的地方,请大家指正和谅解,谢谢!
<完>

posted @ 2006-01-05 19:46 Ben 阅读(276) | 评论 (0)编辑 收藏

金山词霸2000使用密技两则

金山词霸2000使用密技两则

loveaniu

    
 

  金山词霸这么好的软件相信大家都用过吧,可是小生在近日的使用过程中却遇到了两个棘手的问题,经过仔细分析,终于解决,呵呵,好东东当然不能独享,大家请看:

  (一)怎样解决金山词霸在win2000下不能正确显示音标的问题。

  在win2000下装过金山词霸的朋友可能都有词霸不能正确显示单词音标的问题,音标在win2000下被显示成了一堆乱码,这可怎么办呢,我抱着试一试的心理去到金山公司的技术支持那里看能不能找到解决办法,金山的技术支持人员的回答:“出现这类问题时,可能是安装出错或其他软件的字体驱动错误,建议重新安装词霸2000;重装后如果仍然出现问题,则是由于安装了过多的字体,请删掉一些字体再安装或重装Windows系统”。看来只能自己试了,我的win2000里并未装过任何其他的字体,应该不会出现冲突这类事情,那么一定是金山词霸无法调用自己的音标字体而误调用了WINGDING字体造成的,于是我便在金山词霸的安装目录下开始找起来,终于让我找到了那个音标字体——Ksphonet.ttf。呵呵,到这里就好解决了,我们只要把这个字体拷入win2000的fonts目录下就ok了,再开你的词霸试一试,是不是久违的音标又出来了呢?

  (二)怎样解决金山词霸不能在Acrobat中取词翻译的问题。

  许多朋友都希望能在看pdf文件时也能够用金山词霸的取词功能,可是你可能会发现你的金山词霸做不到,这可怎么办呢?呵呵,小生献上终极密技一条,包你随指随取随译,你就一边爽着吧:)方法如下:首先去http://ciba.kingsoft.net/download/acrbatup.zip下载这个补丁,打开后有AcrUpdate.exe和XDICPI32.API 两个文件,你所要做的只是运行AcrUpdate.exe,然后按它所说的一步一步做下去就行了,如果还是不行的话那就只好手工安装了,找到你的Acrobat安装目录,将XDICPI32.API拷入其reader\plug_ins目录下就行了。

硅谷动力eNet

posted @ 2005-12-27 16:57 Ben 阅读(277) | 评论 (0)编辑 收藏

Java 技巧 101:applet 间通信的替代方法

作者 Tobias Hill



摘要
您可能认为能让 applet 彼此通信的唯一选择就是使用 getApplet。不幸的是,getApplet 方法仅返回与发出调用的 applet 在同一个 HTML 页面上的 applet,这样就限制了您通过 applet 间的通信构建有趣界面的方式。这篇技巧说明的替代方法能使处于不同框架甚至不同浏览器窗口中的 applet 彼此调用对方的方法。

java.applet 包中的 AppletContext 类包含两个成员方法,即 getApplet 和 getApplets。通过使用这两个方法,一个 applet 就可以找到其他 applet 并调用它们的方法。要这样做必须满足下面的安全要求:

  • 这些 applet 来自同一个服务器上的同一个目录中。
  • 这些 applet 运行于同一个浏览器窗口中的同一个页面上。

    这样设计安全限制可能有很好的原因;但是,后一个要求限制了利用 applet 间的通信制作有趣的多 applet 界面的方式。

    试考虑这样一种情况:

    您刚编好一个很好的股票市场交易 applet,并决定为它编写一个良好的帮助系统。您希望帮助系统也是一个 applet,并希望将它与股票市场交易 applet 在不同的浏览器框架中运行。您作出这个决定可能是出于网站结构方面的考虑,也可能是出于始终显示帮助系统的需要。另外,您希望使帮助系统根据用户当前在股票交易 applet 中进行的操作转至正确的信息/指导(就像 Microsoft Office 套件中的“回形针”一样)。您甚至计划在帮助系统中编制向导,这些向导可远程指出问题,并可远程执行股票市场交易 applet 中的任务。

    这一方案中体现的思想很不错。但是,因为这两个 applet 处于不同的页面上,所以 AppletContext 中的 Java API 无法帮助您实现这个想法 -- 但这篇技巧可以帮助您。


    使用 AppletContext API

    在说明 applet 间通信的替代机制前,我将首先简要说明一下 getApplet 和 getApplets 这两个方法是如何工作的。一个 applet 通过使用 getApplet 方法可以按名称找到同一个 HMTL 页面中的另一个 applet,而通过使用 getApplets 方法可以找到同一个页面上的所有 applet。这两个方法如果成功执行,则会向调用者返回一个或多个 Applet 对象。调用者一旦找到一个 Applet 对象,它就可能调用这个 Applet 的公用方法。

    假定有下面这样一段 HTML 代码:
    PHP代码:
    <applet code="Applet1" width="400" height="100" name="app1">
    </
    applet>

    <
    applet code="Applet2" width="400" height="100" name="app2">
    </
    applet>

    通过使用 applet 标记中的 name 属性,您就可以用下面的方式引用一个特定的 applet:
    PHP代码:
    Applet theOtherApplet = getApplet("app1");
    theOtherApplet.anyMethod(); //调用任一个公用方法

    或者,您也可以用以下的代码来检索这个页面上的所有 applet:
    PHP代码:
    Enumeration allAppletsOnSamePage = getApplets();
    while(
    allAppletsOnSamePage.hasMoreElements()) {
    Applet appl = (Applet) allAppletsOnSamePage.nextElement();
    appl.anyMethod(); //调用任一个公用方法
    }

    当发出调用的 applet 在它所在的同一个 HTML 页面上检索到一个或几个 applet 之后,它就可以调用这些 applet 的公用方法。

    使用静态数据结构

    不幸的是,如果使用标准方法,则只能与同一个 HTML 页面中的 applet 通信。幸运的是,您很容易就可以避开这个限制。使 applet 间跨页面通信的方法基于这样一个事实,即如果两个 applet 的 codebase 相同,则即使它们是在不同的浏览器窗口中被加载的,它们也共享同一个运行时环境。粗略地说,codebase 就是从中加载 applet 的那个目录。请参阅文后的参考资源,其中有一个链接指向有关 codebase 的一篇教程。

    由于运行时环境是共享的,因此所有 applet 实例都可以访问静态域和静态结构,这样这些静态域和结构就可用来在不同 applet 之间传递信息。

    applet 不仅可以存储诸如整数、字符和字符串这样的简单数据类型,而且每个 applet 都可以将其自身(实例)的一个引用存储在一个静态域(可能在它自己的类中)中。任何 applet 都可以访问这个域,从而获得指向这个实例的引用。

    这听起来复杂吗?不,一点也不复杂。我首先举一个简单的例子。假定您的一个 applet (AppletA.class) 在一个框架中,而另一个 applet (AppletB.class) 在另一个框架中,而且这两个 applet 都是从同一个 codebase 加载的。

    您现在希望授予 AppletA 访问 AppletB 的公用方法的权限。您必须让 AppletB 将其自身的一个引用存储在一个静态公用域中,就像下面这样:
    PHP代码:
    public class AppletB {
    public static
    AppletB selfRef = null; // 初始归零

    public void init() {
    // 生成对该实例的引用
    selfRef = this;
    }
    ...
    }

    现在您就可以从 AppletA 访问 AppletB 的实例了:
    PHP代码:
    public class AppletA {
    AppletB theOtherApplet = null;

    public
    void callAppletB() {
    // 获取静态域,其中存储着指向 AppletB 的
    // 实例的指针。
    theOtherApplet = AppletB.selfRef;

    // 此后就可以调用实例方法了,
    // 如下所示...
    theOtherApplet.repaint();
    }
    ...
    }

    这就是我们所要做的全部工作。因为运行时环境是由不同的 applet 共享的,所以即便 applet 不在同一个页面上,这个方法同样奏效。

    值得注意的一点是,上面的代码并没有处理在启动 AppletB 之前就调用 AppletA 中的 callAppletB 方法的情况。如果发生这种情况,则 selfRef 将是 null,这样不能进行任何通信。

    一种更通用的方法

    当然,还有一种更通用的方法。您可以创建这样一个类,创建它的唯一目的就是在静态数据结构中存储 applet 的引用。稍后您将看到的 AppletList 类就属于这种情况。希望其他 applet 访问自己的公用方法的 applet 实例通过 AppletList 将自己注册。按照 AppletContext.getApplet(string name) 中的模式,每个注册项都与一个字符串相关联。当一个 applet 调用某个 applet 的引用时,这个字符串就起关键字的作用。

    通常,applet 是按下面的方式注册的:
    PHP代码:
    public class AppletA {
    public
    void start() {
    AppletList.register("Stock-trade-applet", this);
    ...
    }
    }

    另一个 applet 获取对它的访问权:
    PHP代码:
    public class AppletB {
    public
    void run() {
    AppletA tradeApplet =
    (
    AppletA) AppletList.getApplet("Stock-trade-applet");
    ...
    }
    }

    当该 applet 停止运行时,您必须紧记在 AppletList 中撤销注册:
    PHP代码:
    public void stop() {
    AppletList.remove("Stock-trade-applet");
    ...
    }

    AppletList 类的完整源代码如下所示:
    PHP代码:
    0: import java.util.*;
    1: import java.applet.Applet;
    2:
    3: public class AppletList {
    4: private static Hashtable applets = new Hashtable();
    5:
    6: public static void register(String name, Applet applet) {
    7: applets.put(name,applet);
    8: }
    9:
    10: public static void remove(String name) {
    11: applets.remove(name);
    12: }
    13:
    14: public static Applet getApplet(String name) {
    15: return (Applet) applets.get(name);
    16: }
    17:
    18: public static Enumeration getApplets() {
    19: return applets.elements();
    20: }
    21:
    22: public static int size() {
    23: return applets.size();
    24: }
    25: }

    要获得说明如何使用这个类的示例,请在参考资源中下载 exampleCode.zip。

    局限性

    正如我在前面提到的那样,必须从同一个 codebase 中加载这些 applet。此外,如果浏览器的两个不同副本正在运行,并且 applet 被加载到每个副本中,则 applet 可能无法彼此通信(取决于浏览器的版本和设置),因为它们可能不再共享同一个运行时环境。但是,如果是浏览器本身衍生出新的浏览器窗口,则没有任何问题。

    该技巧已在几个平台和几个浏览器版本中通过测试,但在某些配置中每个 applet 的运行时环境可能是独立的。该技巧已在下面的操作系统和浏览器组合中通过测试:
  • Windows2000: Internet Explorer 5.0,Internet Explorer 5.5,Netscape Navigator 4.72,Opera 4.01
  • Windows 98: Internet Explorer 4.72,Internet Explorer 5.0,Netscape Navigator 4.02
  • Mac OS 9: Internet Explorer 4.5,
  • Netscape Navigator 4.5
    Red Hat 6.2: Netscape Navigator 4.73

    小结

    这篇技巧说明了能使 applet 彼此通信的一种替代方法。这种方法以 Java API 的 getApplet() 方法不支持的方式工作。这篇技巧中介绍的知识增大了将 applet 作为网站或内部网的一部分的可能性 -- 可以用它替代或补充 getApplets 方法。

    作者简介

    Tobias Hill 是 Citerus 的创办者之一,该公司以瑞典为基地,致力于在 Java 平台上构建因特网、内部网和外部网系统。Hill 从 1996 年开始用 Java 编程,参与了许多项目,从为自主控制的机器人编程到开发在线焰火明信片制作程序等等。

    参考资源

    * 说明如何使用 AppletList 类的示例:
    exampleCode.zip
    * Sun 提供的关于 applet 间通信的 Java 教程:
    http://web2.java.sun.com/docs/books...tsonly/iac.html
    * Sun 提供的有关 codebase(在其他问题中)的 Java 教程:
    http://web2.java.sun.com/docs/books...sonly/html.html
    * 查看以前的所有 Java 技巧以及提交您自己的技巧:
    http://www.javaworld.com/javatips/j...tips.index.html
  • posted @ 2005-12-23 17:06 Ben 阅读(359) | 评论 (0)编辑 收藏

    [转贴]2005年11月程序语言世界排行榜-Java居首位

    摘要:
    近日来,在TIOBE程序员社区中公布了其2005年11月的程序语言排行榜。这得注意的是PHP即将超过C++成为了排行榜的老三!而Java作为开源先锋首当其冲的成为了龙头老大,并且仍然保持着很好的增长势头。



    转载:转载请保留本信息,本文来自http://www.matrix.org.cn/resource/news/315.html


    版权申明:转载必须保留以下信息
    作者:cleverpig

    可以自由转载, 转载请保留下面的作者信息:

    作者 cleverpig(http://www.matrix.org.cn/blog/cleverpig)


    近日来,在TIOBE程序员社区中公布了其2005年11月的程序语言排行榜。这得注意的是PHP即将超过C++成为了排行榜的老三!而Java作为开源先锋首当其冲的成为了龙头老大,并且仍然保持着很好的增长势头。

    这个排行榜每月更新一次,其排名顺序按照世界范围内的技术工程师、讲师、第三方厂商的调查依据,并查询了目前流行的搜索引擎:Google,MSN,Yahoo,结合前两者的数据计算后得出的。根据TIOBE的观点,此排行榜是被程序员们用来检查自己的程序技能是否过时,或者作为建立新的软件系统时进行参考之依据,并非意味着哪种语言是最好的。

    1。世界前20位语言排行榜:




    2。世界前10位语言在前五年内长期发展趋势图:




    3。世界前30-50位语言排行榜:







    图示说明:
    * (Position):此列表明当前语言与去年位置的变化。
    * Ratings:在查询搜索引擎计算排名顺序时使用了 '+" programming" -tv -channel'公式,对上12个月内Google,MSN,Yahoo!和Google新闻组的数据进行查询。注意此公式应用于标准的Google web点击率、标准的MSN web点击率、标准的Yahoo!web点击率和标准的Google新闻组点击率。这里的“标准”意味着一次对前50位语言web点击率总和的查询是均匀分布的,即保证了排名的相对公正性和科学性。
    * (Ratings): 此列表明当前语言在上12个月内的排名变化。
    * Status:带有“A”的程序语言被认为是主流语言。
    带有“A-”和“A--”表示程序语言位于“A”和“B”之间。
    从支持能力的观点看,尽量在工业的、任务危机的软件系统中使用带有“A”的主流程 序语言。
    如果某种语言在上3个月内具有超过0.7%的增长率,则此语言将获得“A”状态。上两个月内具有超过0.7%的增长率的程序语言相应的将获得“A--”和“A-”状态。

    posted @ 2005-12-23 16:53 Ben 阅读(320) | 评论 (0)编辑 收藏

    你是否需要XML?

    XML是现在很热门的一个话题,但是实际上它能为你的公司做些什么?你需不需要配置XML呢?大家只有对XML有所了解之后才能做出正确的评估,然后才能真正决定是否采用XML。通过权衡利弊,能够帮助你做最后的决定。


    XML如何被使用?

    XML对于描述那些要被应用程序所使用的数据来说是一种非常出色的工具。这是由于绝大多数基于网络的应用软件是使用这些数据制作出来的,而对于XML来说,它已经发展成为了网络服务的一种标准。



    你可以在企业里的许多层次上都使用XML。XML经常被用来存储那些会出现在网络站点的内容。你还可以把XML用作内部的信息存储库,这个库是可以被第三方应用软件所访问的,而且不需要具备数据库相关的功能。



    从内部移动到外部应用软件,XML可以让你和合作者之间以一种有协议的方式进行数据交换。你可以维持你系统原来的状态,而不用去考虑合作者系统的结构。

    采用XML的有利条件

    许多企业采用XML的主要原因是由于它允许与外部的合作者进行方便的集成。可能有三个提供商在为你服务,他们都有自己的系统,但是都需要访问相同的数据。XML允许你把数据制作成一种格式,让这三者都能够通过他们自己的系统来获取和使用这些信息。



    很明显,XML是由于它本身的简便易用以及节省时间的信息集中化管理而流行起来的。



    在适当的环境里,使用XML还有其它的一些好处。当处理网络应用软件的时候,把数据装入XML文件然后再由应用软件进行分析的方法能够有效的简化保持维护的复杂性。这就不用再更换菜单、页面标题以及内容了。在许多情况下,只需简单的编辑XML文件就能够完成这些改变。



    XML还可以方便的用于扩展存储于文件中的内容和内容的类型。虽然这可能会比访问数据库要花去更多的时间,但是如果只有相关的信息被存储在文件中的话,那么,处理的时间则会被缩短。你可以使用编程语言中的查找与分类功能来实现,而不是使用数据库中的相关功能。但是,总的来说,XML的内容是有意被显示出来的,而且该过程也不是必需的。

    网络服务对P2P的贡献

    另一个很大的好处是你可以简单的就加入相关数据的子集,能够禁止系统访问那些没有被使用的信息。

    采用XML的缺点

    当然,所有的事情都有两面性,使用XML也有一些缺点,这些缺点会让你在真正使用它之前会再审慎的考虑一番。举例来说,XML有可能会产生非常不便于维护的相当巨大的数据量。由于这个原因,人们通常会把数据存储在数据库中,然后才把输出的相关信息送入XML。在这种情况下,你实际上并不把信息保存在XML文件中。这种情况是否被看作是一个不利条件还不确定,但是还是有必要在作决定之前考虑一下这种情况。



    XML有一个明显的缺点,就是缺少完整的安全保护。一个共享的XML文件对于请求的回应是自动的。如果你把该文件加密以寻求安全保护,那么,接收端就不能够自动的识别出它的内容。XML有几种可以使用的安全标准,但是还没有最后确定选择哪一个标准。



    因此,公司就需要限制他们的文件在VPN或者外部网络上的发布。否则这些公司就会冒一定的风险,因为任何人都知道在国际互联网上如何浏览包含有重要信息的XML文件。



    控制访问也会带来一系列的问题。到安全标准被真正实现之前,唯一可信赖的方法就是为不同的人提供你信息的不同子集,这样做能够为不同的人创建分开的XML文件。如果你试图把XML作为企业B2B解决方案主要组成部分,并且还需要为每一方都进行用户化,那么,选择使用数据库可能比选择使用包含大量XML文件的方式要好得多。

    如何做决定?

    在做决定之前,要考虑一下你要完成什么样的目标,是否使用XML能让完成这个目标变得更加容易。你是否正试图传送相同的或者相关的信息给不同的人,这些人在他们的终端上都使用不同的软件。如果是这样的话,XML是你的好选择。你是否希望能够方便的维护你的网络站点而不用依靠数据库呢?那么,也可以选择XML。



    然而,如果你处理的是比较敏感而且重要的数据,又或者你正在把你数据的不同部分传送给不同的目标,那么,你就会希望能够得到更多的安全保护。如果你的解决方案中包含为相似的服务创建多个XML文件,你的选择可能有些超前了,而且有可能会导致维护上的灾难。



    对于local应用软件,你可能会需要考虑一下具体配置的每一个细节。如果安全和访问都不是问题的话,考虑一下,把你的信息都集中到一个XML源是否能够让你从中获得好处。如果你需要显示这些数据,并且还会出现在不同的地方,那么,XML对于网络服务来说就是一个很好的选择。

    总结

    如果你对于使用XML已经有所准备,那么你就要考虑一下数据的类型和工作的环境了,这些都能够帮助你决定这是否是一个很好的解决方案。如果这么做有很明显的好处,而且你并不介意安全上的问题,那么,你只要多投入些注意力和智慧就可以了。否则,你可能就会希望别的人先于你这么做,而你等到时机成熟了才会选择这样的解决方案。

    posted @ 2005-12-23 16:49 Ben 阅读(331) | 评论 (0)编辑 收藏

    快速精确的对数学表达式求值

    快速精确的对数学表达式求值 英文原文
    内容:
    表达式求值的经典算法
    W3Eval:一种新的方法
    结论
    参考资料
    关于作者
    对本文的评价
    相关内容:
    教程:Building a Java applet
    更多 dW Java 参考资料
    使用这个方便的 applet ,您就能一步一步的计算数学表达式了 Nikola Stepan (nikola.stepan@vz.tel.hr)
    软件工程师,ABIT Ltd.
    2001 年 9 月
    对于未经训练的用户来说,计算机科学领域中数学表达式求值的传统方法即不顺手又难以使用;软件工程师 Nikola.Stepan 旨在改变这些传统方法。他的 applet W3Eval 对表达式求值与您用纸笔计算的一系列步骤完全一致,但更快并且没有错误。请往下读,了解这一挑战 — 人类易读的数学到 Java 代码的转换。
    还记得在您的第一台科学计算器上用逆波兰表示法奋斗的经历吗?W3Eval applet 无法让您可信赖的 HP-41 更易用,正如它的名称所暗示 — 一个只能运行于 Web 的表达式求值程序。但它的确提供了一种方法 — 人类更易于遵循的对表达式一步一步的求值。

    W3Eval 的方法与传统计算器不同,却和人类的计算方式一致。当您用传统的计算器计算时,每输入一个新数,前一个数就看不到了。如果在输入一个长表达式中出了错,就得全部重来。有了 W3Eval,您就能看到参与计算的所有东西,还能轻松的编辑表达式。它独特的能力(一步一步的对表达式求值)非常容易实现,因为用户能看到求值的每一步,包括临时结果。

    本文将让您从头至尾认识 W3Eval 功能性的要点;您将看到一些用于表达式求值的代码。不过,我们还是先看看表达式求值的经典算法,这样您就会明白 W3Eval 方法的差异究竟有多少。

    表达式求值的经典算法
    编写代码对算术表达式求值的经典方法由 Donald Knuth 描述于 1962 年(请参阅参考资料)。Knuth 将此概括为三个步骤:
    • 对中缀表达式进行语法分析
    • 中缀表达式到后缀表达式的转换
    • 对后缀表达式求值
    注意到我们谈到的这个经典算法有些简化:算术表达式只包含操作数、二元操作符和一种括号。此外,对于每个操作数和操作符,只用单个字符表示,使语法分析直观。

    表达式表示法
    算术表达式中最常见的表示法形式有中缀、前缀后缀表示法。中缀表示法是书写表达式的常见方式,而前缀和后缀表示法主要用于计算机科学领域。

    中缀表示法
    中缀表示法是算术表达式的常规表示法。称它为中缀表示法是因为每个操作符都位于其操作数的中间,这种表示法只适用于操作符恰好对应两个操作数的时候(在操作符是二元操作符如加、减、乘、除以及取模的情况下)。对以中缀表示法书写的表达式进行语法分析时,需要用括号和优先规则排除多义性。



    Syntax: operand1 operator operand2Example: (A+B)*C-D/(E+F)
    前缀表示法
    前缀表示法中,操作符写在操作数的前面。这种表示法经常用于计算机科学,特别是编译器设计方面。为纪念其发明家 — Jan Lukasiewicz(请参阅参考资料),这种表示法也称波兰表示法



    Syntax : operator operand1 operand2Example : -*+ABC/D+EF
    后缀表示法
    在后缀表示法中,操作符位于操作数后面。后缀表示法也称逆波兰表示法(reverse Polish notation,RPN),因其使表达式求值变得轻松,所以被普遍使用。



    Syntax : operand1 operand2 operatorExample : AB+C*DEF+/-
    前缀和后缀表示法有三项公共特征:
    • 操作数的顺序与等价的中缀表达式中操作数的顺序一致
    • 不需要括号
    • 操作符的优先级不相关
    中缀表达式到后缀表达式的转换
    要把表达式从中缀表达式的形式转换成用后缀表示法表示的等价表达式,必须了解操作符的优先级和结合性。优先级或者说操作符的强度决定求值顺序;优先级高的操作符比优先级低的操作符先求值。 如果所有操作符优先级一样,那么求值顺序就取决于它们的结合性。操作符的结合性定义了相同优先级操作符组合的顺序(从右至左或从左至右)。



    Left associativity : A+B+C = (A+B)+CRight associativity : A^B^C = A^(B^C)
    转换过程包括用下面的算法读入中缀表达式的操作数、操作符和括号:
    1. 初始化一个空堆栈,将结果字符串变量置空。
    2. 从左到右读入中缀表达式,每次一个字符。
    3. 如果字符是操作数,将它添加到结果字符串。
    4. 如果字符是个操作符,弹出(pop)操作符,直至遇见开括号(opening parenthesis)、优先级较低的操作符或者同一优先级的右结合符号。把这个操作符压入(push)堆栈。
    5. 如果字符是个开括号,把它压入堆栈。
    6. 如果字符是个闭括号(closing parenthesis),在遇见开括号前,弹出所有操作符,然后把它们添加到结果字符串。
    7. 如果到达输入字符串的末尾,弹出所有操作符并添加到结果字符串。
    后缀表达式求值
    对后缀表达式求值比直接对中缀表达式求值简单。在后缀表达式中,不需要括号,而且操作符的优先级也不再起作用了。您可以用如下算法对后缀表达式求值:
    1. 初始化一个空堆栈
    2. 从左到右读入后缀表达式
    3. 如果字符是一个操作数,把它压入堆栈。
    4. 如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您不能够弹出两个操作数,后缀表达式的语法就不正确。
    5. 到后缀表达式末尾,从堆栈中弹出结果。若后缀表达式格式正确,那么堆栈应该为空。
    W3Eval:一种新的方法
    W3Eval 的方法与上面概括的经典算法不同。不是把中缀表达式转换为后缀表示法;恰恰相反,它对中缀表达式直接求值。这种方法比传统方法稍微复杂了些,但它支持一步一步的求值,在执行时您能看到每一步。求值过程类似于手工计算:如果表达式中包含括号,先求嵌套最深的括号对中的子表达式的值。所有括号内的子表达式都求值完毕后,表达式的其它部分再求值。

    求值过程分为三个步骤:
    1. 表达式语法分析
    2. 表达式检查
    3. 一步一步的求值
    表达式语法分析
    W3Eval 的数学表达式由数字、变量、操作符、函数和括号组成。除了缺省的十进制计数制外 W3Eval 还支持二进制、八进制和十六进制。这些以其它计数制计数的数必须以 # 开头,并紧跟 bo 或者 h 来分别表示二进制、八进制或十六进制。

    W3Eval 的变量是不限长度的大写字母和数字序列,其首字符必须是字母。W3Eval 有一些预定义的变量,不过它也支持用户定义的变量。

    W3Eval 支持带有固定或不定数量自变量的函数。 函数可分为以下几组:
    • 三角函数(sin、cos、tan、cot、sec、csc)
    • 反三角函数(asin、acos、atan、atan2、acot、asec、acsc)
    • 双曲线函数(sinh、cosh、tanh、coth、sech、csch)
    • 反双曲线函数(asinh、acosh、atanh、acoth、asech、acsch)
    • 指数函数(log、log2、log10、exp、exp2、exp10、sqrt、cur)
    • 组合学函数(Combinatoric)(comb、combr、perm、permr、var、varr)
    • 统计函数(sum、avg、min、max、stddev、count)
    • 其它(abs、ceil、fact、floor、pow、random、rint、round、sign、frac、hypot、deg、rad、trunc、int)
    W3Eval 对表达式进行语法分析,也就是指它识别出表达式的算术成分,并将它们转化成语言符号(token),然后把它们放入向量。表达式一旦处于这种状态,就为下面两步做好了准备:表达式检查和求值。

    W3Eval 的符号(token)是算术表达式的组成部分;记号(mark) 是独立的字符, 由 applet 使用,作为识别各种符号的内部标志。每种符号有唯一的 mark 与之对应。W3Eval 的表达式由表 1 所示的符号组成。

    表 1. W3Eval 的符号
    Token Mark
    十进制数 Double
    二进制数 String
    十六进制数 String
    八进制数 String
    变量 Variable
    函数 Function
    操作符 Operator
    开括号 String
    闭括号 String
    逗号 String


    用以表示函数、操作符和变量类的定义如清单 1 所示:

    清单 1. Function、Operator 和 Variable 类的定义


    public class Function { public String function; public int number_of_arguments; public Function( String function, int number_of_arguments ) { this.function=function; this.number_of_arguments=number_of_arguments; } public String toString() { return function; } }public class Operator { public String operator; public byte priority; public Operator( String operator, byte priority ) { this.operator=operator; this.priority=priority; } public String toString() { return operator; } }public class Variable { public String variable; public double value; public Variable( String variable, double value ) { this.variable=variable; this.value=value; } public String toString() { return variable; } }
    Token 类如清单 2 所示。

    清单 2. Token 类


    public class Token { public Object token; public char mark; public int position; public int length; public Token ( Object token, char mark, int position, int length ) { this.token=token; this.mark=mark; this.position=position; this.length=length; } public String toString() { return token.toString()+" ; "+mark+" ; "+position+" ; "+length+""; } }
    表达式检查
    检查正规表达式正确性的所有代码都在一个独立的类中。详细的表达式检查能够确定错误确切的类型和位置。 错误检查有七类:

    括号检查。W3Eval 的表达式可以包含三种括号:标准圆括号、方括号和花括号。如果表达式包含相同数量的开括号和闭括号,并且每个开括号与一个相应的同种闭括号相匹配,则表达式的括号语法正确。三种括号在语义上等价,如下面的代码段所示。

    清单 3. 三种括号


    import java.util.Stack;public class Parentheses_check { public static boolean is_open_parenthesis( char c ) { if ( c=='(' || c=='[' || c=='{' ) return true; else return false; } public static boolean is_closed_parenthesis( char c ) { if ( c==')' || c==']' || c=='}' ) return true; else return false; } private static boolean parentheses_match( char open, char closed ) { if ( open=='(' && closed==')' ) return true; else if ( open=='[' && closed==']' ) return true; else if ( open=='{' && closed=='}' ) return true; else return false; } public static boolean parentheses_valid( String exp ) { Stack s = new Stack(); int i; char current_char; Character c; char c1; boolean ret=true; for ( i=0; i < exp.length(); i++ ) { current_char=exp.charAt( i ); if ( is_open_parenthesis( current_char ) ) { c=new Character( current_char ); s.push( c ); } else if ( is_closed_parenthesis( current_char ) ) { if ( s.isEmpty() ) { ret=false; break; } else { c=(Character)s.pop(); c1=c.charValue(); if ( !parentheses_match( c1, current_char ) ) { ret=false; break; } } } } if ( !s.isEmpty() ) ret=false; return ret; } }
    token 检查。检查表达式语法。确保表达式所有部分都被认为是合法的。

    表达式开头的检查(请参阅清单 4确保表达式从合法的符号开始。不可以用操作符、逗号或闭括号作为表达式的开始符。





    清单 4. 正确的表达式开头的检查


    private static boolean begin_check( Vector tokens, Range r, StringBuffer err ) { char mark; Token t; t=(Token)tokens.elementAt( 0 ); mark=t.mark; if ( mark=='P' ) err.append( Messages.begin_operator ); else if ( mark==')' ) err.append( Messages.begin_parenthesis ); else if ( mark=='Z' ) err.append ( Messages.begin_comma ); else return true; r.start=0; r.end=t.length; return false; }


    表达式末尾的检查。确保表达式以合法符号结束。不可以用操作符、函数、逗号或开括号作为表达式结束符。

    符号序列的检查。检查表达式中的符号序列。在下面的表格中,若 X 轴上的符号和 Y 轴上的符号对应的交界处用 X 作了记号,则相应 X 轴上的符号可以接在 Y 轴上符号的后面。

    表 2. 合法的符号序列
    _ D B H O V F P ( ) Z
    D _ _ _ _ _ _ _
    B _ _ _ _ _ _ _
    H _ _ _ _ _ _ _
    O _ _ _ _ _ _ _
    V _ _ _ _ _ _ _
    F _ _ _ _ _ _ _ _ _
    P _ _ _
    ( _ _ _
    ) _ _ _ _ _ _ _
    Z _ _ _


    函数检查。确保表达式中所有函数的自变量数量正确。

    逗号检查。逗号只能用于分隔函数的自变量。若用于表达式其它地方,就不合法。

    一步一步的求值
    只有能顺利通过以上概括的所有检查的表达式,W3Eval 才求值。从而确保内建于 W3Eval 中的前提条件不会出现问题。后面的算法用于单步执行表达式求值:
    1. 找出嵌入最深的那对括号。
    2. 在这对括号中,找出优先级最高的操作符。
    3. 若这对括号中没有操作符:
      • 如果表达式再不包含任何其它的括号,求值(过程)完成。
      • 如果表达式包含括号,但不包含操作符,则存在一个函数。对函数求值,然后转到步骤 5。
    4. 获取操作数并执行运算。
    5. 从向量中除去用过的符号并在同一位置放入结果。
    6. 除去冗余括号。
    7. 将向量中剩余的符号结合到字符串并在屏幕上显示结果。
    现在,我们将更为详细的查看算法的每一步,同时查看大部分有意思的代码片段。

    步骤 1:为避免括号的处理,W3Eval 确定哪个子表达式处于嵌套最深的那对括号中。这项任务需要两步。第一步,W3Eval 必须找出第一个闭括号:

    清单 5. 找出第一个闭括号


    public static int pos_first_closed_parenthesis( Vector tokens ) { Token t; for ( int i=0; i
    第二步,找出与第一步找到的闭括号相匹配的开括号,如清单 6 所示





    清单 6. 找出匹配的开括号


    public static int pos_open_parenthesis( Vector tokens, int closed_parenthesis ) { int i; Token t; i=closed_parenthesis-2; while ( i>=0 ) { t=(Token)tokens.elementAt( i ); if ( t.mark=='(' ) { return i; } i--; } return 0; }


    步骤 2:要实现求值的单步执行,W3Eval 在嵌套最深的那对括号中找出优先级最高的操作符。(操作符的优先级已硬编码到 applet 中;请参阅参考资料以获取完整的代码清单。)

    清单 7. 找出优先级最高的操作符


    public static int pos_operator( Vector tokens, Range r ) { byte max_priority=Byte.MAX_VALUE; int max_pos=0; byte priority; String operator; Token t; for ( int i=r.start+2; i<=r.end-2; i++ ) { t=(Token)tokens.elementAt( i ); if ( t.mark!='P' ) continue; priority=((Operator)t.token).priority; operator=((Operator)t.token).operator; if ( priority < max_priority || ( operator.equals("^") || operator.equals("**") ) && priority == max_priority ) { max_priority=priority; max_pos=i; } } return max_pos; }
    步骤 3:如果表达式中不包含其它括号,求值的过程就完成。如果表达式包含括号,但不包含操作符,则存在需要求值的函数。

    清单 8. 检查是否还有其它操作符


    ...int poz_max_op=pos_operator( tokens, range );// if there are no operatorsif ( poz_max_op==0 ) { if ( no_more_parentheses ) { return false; } else { double result; result=function_result( tokens, range.start-1 ); function_tokens_removal( tokens, range.start-1 ); t = new Token ( new Double(result), 'D', 0, 0 ); tokens.setElementAt( t, range.start-1 ); parentheses_removal( tokens, range.start-1 ); return true; } }...
    步骤 4:所有的操作符都是二元的,也就是说第一个操作数位于操作符之前,第二个操作符位于操作符之后。

    清单 9. 获取操作数并执行运算


    ...double operand1, operand2;// first operand is before...t=(Token)tokens.elementAt( poz_max_op-1 );operand1=operand_value( t );// ...and second operand is after operatort=(Token)tokens.elementAt( poz_max_op+1 );operand2=operand_value( t );// operatort=(Token)tokens.elementAt( poz_max_op );String op=((Operator)t.token).operator;double result=operation_result( operand1, operand2, op );tokens.removeElementAt( poz_max_op+1 );tokens.removeElementAt( poz_max_op );t = new Token ( new Double(result), 'D', 0, 0 );tokens.setElementAt( t, poz_max_op-1 );parentheses_removal( tokens, poz_max_op-1 );...
    操作数可以是变量,还可以是十进制、十六进制、八进制或二进制数。

    清单 10. 获取操作数


    public static double operand_value( Token t ) { if ( t.mark=='V' ) return ((Variable)t.token).value; else if ( t.mark=='D' ) return ((Double)t.token).doubleValue(); else if ( t.mark=='H' ) return base_convert( ((String)t.token).substring(2), 16 ); else if ( t.mark=='O' ) return base_convert( ((String)t.token).substring(2), 8 ); else if ( t.mark=='B' ) return base_convert( ((String)t.token).substring(2), 2 ); }
    接下来的方法将不同计数制的数转化为十进制的形式。

    清单 11. 将数转化为十进制数


    public static long base_convert( String s, int base ) { long r=0; int i, j; for ( i=s.length()-1, j=0; i>=0; i--, j++ ) r=r+digit_weight( s.charAt( i ) )*(long)Math.pow( base, j ); return r; }public static int digit_weight( char c ) { if ( Character.isDigit( c ) ) return c-48; else if ( 'A'<=c && c<='f' ) return c-55; else if ( 'a'<=c && c<='f' ) return c-87; return -1; }
    一旦确定操作数和操作符后,就可以执行运算了,如清单 12 所示。

    步骤 5:在这步中,W3Eval 从向量中除去用过的符号并在同一位置放入结果。对于函数求值这类情况,除去的是函数、括号、自变量和逗号;而对于操作符求值这类情况而言,除去的则是操作数和操作符。

    步骤 6:在求值的这一步,W3Eval 从表达式中除去冗余括号。

    清单 13. 除去冗余括号


    private static void parentheses_removal( Vector tokens, int pos ) { if ( pos>1 &&&& ((Token)tokens.elementAt( poz-2 )).mark!='F' &&&& ((Token)tokens.elementAt( poz-1 )).mark=='(' &&&& ((Token)tokens.elementAt( poz+1 )).mark==')' || pos==1 &&&& ((Token)tokens.elementAt( 0 )).mark=='(' &&&& ((Token)tokens.elementAt( 2 )).mark==')' ) { tokens.removeElementAt( poz+1 ); tokens.removeElementAt( poz-1 ); } return; }
    步骤 7:在求值的最后一步,向量中剩余的符号被结合到字符串,并在屏幕上显示。

    清单 14. 结合符号并显示结果


    public static String token_join( Vector tokens ) { String result=new String(); Token t; for ( int i=0; i < tokens.size(); i++ ) { t=(Token)tokens.elementAt( i ); if ( t.mark=='D' ) { double n=((Double)t.token).doubleValue(); result=result + formated_number( n ); } else result=result + t.token; if ( result.endsWith( ".0" ) ) result=result.substring( 0, result.length()-2 ); result=result + " "; } return result; }
    结论
    本文分析了一个 applet ,它能一步一步的对算术表达式求值。同时还按顺序回顾了最有意思的代码片段,并论述了两种不同的表达式求值方法。

    下一版 W3Eval 有望在各方面得到增强,包括有能力添加用户定义的功能;支持分数、复数和矩阵;改良的图形用户界面(GUI);大小和速度优化以及安全性方面的增强。我鼓励您提供您自己对于增强方面的设想。

    我希望您会发现 W3Eval 是个对表达式求值有益的在线工具,它在某种程度上比经典的方法更简单自然。我还期待这里谈到的代码和算法使您明白 Java 语言有助于处理数学问题。

    参考资料
    • W3Eval applet 是免费的,它的帮助有助于您解决问题。
    • 这张表格展示了 W3Eval 操作符的优先级
    • 请阅读波兰数学家 Jan Lukasiewicz 的传记。
    • Donald Knuth,计算机科学领域卓越的学者,曾详尽的就算法的设计和分析撰写和演讲。他的主页提供最近出版的有关其作品的论文和信息的链接。
    • 有兴趣随意编写 applet 吗?可以查看我们的教程 Building a Java applet(developerWorks,1999 年)以获得一步一步的指导。
    • 您会觉得 Java FAQ 很有用。
    • 还有很多有关 applet 的信息在 Peter Van Der Linden(Prentice Hall PTR/Sun Microsystems 出版社出版,1998 年 12 月)的Just Java 2 中。
    • 由 Ken Arnold、James Gosling 和 David Holmes 撰写的 The Java Programming Language(Addison Wesley 出版社出版,2000 年 12 月)包含有益的关于集合的信息。
    • 学习 Martin Bastiaan 的“A Walk in the Park”(developerWorks,1998 年 1 月),了解更多有关 applet 的知识。
    • VisualAge for Java 使 applet 的开发变得轻而易举。
    • developerWorks Java 技术专区查找更多 Java 参考资料。

    关于作者
    Nikola Stepan 是 ABIT Ltd. 的软件工程师,他在那里从事银行业软件的设计和开发。他有广博的信息系统方面的学术背景和丰富的编程经验(从低级编程到信息系统)。他特别喜欢面向对象编程语言、关系数据库、因特网编程和系统编程。他于 1999 年在克罗地亚 Varazdin 的 Faculty of Organisation and Informatic 获得信息系统学士学位。他会说克罗地亚语、英语和一点德语。请通过 nikola.stepan@vz.tel.hr 与 Nikola 联系。
    __________________
    “日本固有新奇的武器,我当以热血应付;日本固有猛烈的枪炮,我当以头颅拼挡。”
    “作为军人,志在以身报国,苟有一线之机不减,自应鼓舞勇气,而为国家尽其最后之牺牲。凡为官为吏,不过一时职业之选择,民族之保存,始为骨头之归宿!”

    posted @ 2005-12-23 16:28 Ben 阅读(1319) | 评论 (0)编辑 收藏

    仅列出标题
    共3页: 上一页 1 2 3 下一页