??xml version="1.0" encoding="utf-8" standalone="yes"?>
实现ҎQ在PHP讑֮(configure)时加入如下选项?
q样׃得你的PHPpȝ可以处理相关的IPC函数了?
IPC是什么?
IPC (Inter-process communication) 是一个Unix标准通讯机制Q它提供了得在同一CZ同进E之间可以互盔R讯的方法。基本的IPC处理机制?U:它们分别是共享内存、信号量和消息队列。本文中我们主要讨论׃n内存和信号量的用。关于消息队列,W者在不久的将来还会专门介l?
在PHP中用共享内存段
在不同的处理q程之间使用׃n内存是一个实C同进E之间相互通讯的好Ҏ。如果你在一个进E中向所׃n的内存写入一D信息,那么所有其他的q程也可以看到这D被写入的数据。非常方ѝ在PHP中有了共享内存的帮助Q你可以实现不同q程在运行同一DPHP脚本时返回不同的l果。或实现对PHP同时q行数量的实时查询等{?
׃n内存允许两个或者多个进E共享一l定的存储区。因为数据不需要在客户机和服务器之间复Ӟ所以这是最快的一UIPC。用共享内存的唯一H门是多个进E对一l定存储区的同步存取?
如何建立一个共享内存段呢?下面的代码可以帮你徏立共享内存?nbsp;
注意Q每个共享内存段都有一个唯一的ID, 在PHP中,shmop_open会把建立好的׃n内存D늚IDq回Q这里我们用$shm_id记录它。?key是一个我们逻辑上表C共享内存段的Key倹{不同进E只要选择同一个Key id可以共享同一D存储段。习惯上我们用一个串Q类似文件名一L东西Q的散列g为key id. $mode指明了共享内存段的用方式。这里由于是新徏Q因此gؓ’c’ –取create之意。如果你是访问已l徏立过的共享内存那么请?#8217;a’,-- 取Access之意?perm参数定义了访问的权限Q?q制Q关于权限定义请看UNIX文gpȝ帮助?size定义了共享内存的大小。尽有点象fopen(文g处理)你可不要当它同文件处理一栗后面的描述你将看到着一炏V?
例如Q?
q里我们打开了一个共享内存段 键?xff3 –rw-r—r—格式,大小?00字节?
如果需要访问已有的׃n内存D,你必d调用shmop_open中设W??个参Cؓ0?
IPC工作状态的查询
在Unix下,你可以用一个命令行E序ipcs查询pȝ所有的IPC资源状态。不q有些系l要求需要超U用h能执行。下图是一Dipcs的运行结果?/p>
上图中系l显CZ4个共享内存段Q注意其中第4个键gؓ0x00000ff3的就是我们刚刚运行过的PHPE序所创徏的。关于ipcs的用法请参考UNIX用户手册?
如何释放׃n内存?
释放׃n内存的办法是调用PHP指o:shmop_delete($id)
$id 是你调用shmop_open所存的shmop_op的返回倹{还有一个办法就是用UNIX的管理指?
ipcrm id, id是你用ipcs看到的ID.和你E序中的$id不一栗不q要心Q如果你用ipcrm直接删除׃n内存D那么有可能D其他不知道这一情况的进E在引用q个已经不复存在的共享内存器时出C些不可预的错误(往往l果不妙)?
如何使用(d)׃n内存?
使用如下所C函数向׃n内存写入数据
其中shmid是用shmop_openq回的句柄?Data变量存放了要存放的数据?offset描述了写入从׃n内存的开始第一个字节的位置Q以0开始)?
d操作是:
同样Q指?shmid,开始偏U量Q以0开始)、总读取数量。返回结果串。这P你就可以把共享内存段当作是一个字节数l。读几个再写几个Q想q嘛干嘛,十分方便?
多进E问题的考虑
现在Q在单独的一个PHPq程中读写、创建、删除共享内存方面上你应该没有问题了。但是,昄实际q行中不可能只是一个PHPq程在运行中。如果在多个q程的情况下你还是沿用单个进E的处理ҎQ你一定会到问题 ---- 著名的ƈ行和互斥问题。比如说?个进E同旉要对同一D内存进行读写。当两个q程同时执行写入操作Ӟ你将得到一个错误的数据Q因D内存将之可能是最后执行的q程的内容,甚至是由2个进E写入的数据轮流随机出现的一D|合的四不象。这昄是不能接受的。ؓ了解册个问题,我们必须引入互斥机制。互斥机制在很多操作pȝ的教材上都有专门讲述Q这里不多重复。实C斥机制的最单办法就是用信L。信号量是另外一U进E间通讯(IPC)的方式,它同其他IPC机构(道、FIFO、消息队?不同。它是一个记数器Q用于控制多q程对共享数据的存储。同L是你可以用ipcs和ipcrm实现对信L使用状态的查询和对其实现删除操作。在PHP中你可以用下列函数创Z个新的信号量q返回操作该信号量的句柄。如果该key指向的信号量已经存在Qsem_get直接q回操作该信号量的句柄?
$max_acquire 指明同时最多可以用几个q程q入该信可不必等待该信号被释放(也就是最大同时处理某一资源的进E数?一般该值均ZQ?perm指明了访问权限?
一旦你成功的拥有了一个信号量Q你对它所能做的只?U:h、释放。当你执行释放操作时, pȝ把该信号值减一。如果小?那就q设?。而当你执行请求操作时Q系l将把该信号值加一Q如果该值大于设定的最大值那么系l将挂v你的处理q程直到其他q程释放到小于最大gؓ止。一般情况下最大D?,q样一来当一个进E获得请求时其他后面的进E只能等待它退Z斥区后释放信号量才能q入该互斥区q同时设为独占方式。这L信号量常UCؓ双态信号量。当Ӟ如果初值是L一个正数就表明有多个׃n资源单位可供׃n应用?
甌、释放操作的PHP格式如下Q?
甌
释放
其中sem_identifier是调用sem_get的返回|句柄Q?nbsp;
一个简单的互斥协议例子
下面是一D很单的互斥操作规程?
正如你所看到的,互斥的实现很单:甌q入临界区,对界区资源q行操作Q比如修改共享内存)退Z界区q放信受这样一来就可以保证在同一个时间片中不可能有同?个进E对同一D共享内存进行操作。因Z号量机制保证一个时间片只能׃个进E进入,其他q程必须{待当前处理的进E完成后方能q入?
临界Z般是指那些不允许同时有多个进Eƈ发处理的代码Dc?
要注意的?在PHP中必ȝ同一个进E释攑֮所占用的信号量。在一般系l中允许q程释放别的q程占用的信受在~写临界Z码一定要心设计资源的分配,避免A{BQB{A的死锁情况发生?nbsp;
q?/strong>
IPC的运用是十分q泛的。比如,在不同进E间保存一个解释过的复杂的配置文g、或具体讄的用LQ以避免重复处理。我也曾l用׃n内存的技术把一大批PHP脚本必须引用的一个很大的文g攑օ׃n内存Qƈ由此显著提升了Web服务的速度、消除了部分瓉。关于它的用还有聊天室Q多路广播等{。IPC的威力取决于你的惌力的大小。如果本文对你有一点点启发Q那我不胜荣q。愿意很你讨令h入迷的电脑技术。Email: qwyaxm@163.net
本期介绍多个XSL对于VBScript、JScript增加的方法、属性,以充分发挥XML的优势,用于<xsl:script>?lt;xsl:eval>标记内表辑ּ的编写或<xsl:if>?lt;xsl:when>的expr属性?/p>
一、absoluteChildNumber
含义Q返回结点相对于它所有的兄弟Q不论名字是否相同)的序受?/p>
语法QabsoluteChildNumber(node)
参数Qnode ── 对象Q欲q回~号的结炏V?/p>
CZQ?/p>
1、假定文档结构ؓQ?lt;document><head/><body/></document>Q其中document为顶层结点,下述表达式将输出Q?br />
二、ancestorChildNumber
含义Q从l定l点出发Ҏl定先l点名返回最q的先l点的序P相对于同名结点)。如果找不祖先,则返??/p>
语法QancestorChildNumber(bstrNodeName, pNode)
参数Q?/p>
bstrNodeName ── 字符丌Ӏ被搜烦的祖先结点的名字?/p>
pNode ── 对象。搜索开始位|的l点?/p>
CZ查找当前l点最q的名ؓreport先l点Q?/p>
ancestorChildNumber('report',this)
三、attributes
含义Q返回结点属性的集合?/p>
语法Qobject.attributes
参数Qobject ── l点对象?/p>
CZQ当前结点属性的个数
this.attributes.length
当前l点W三个属性的?/p>
this.attributs.item(2).value
?br />
this.attributes.item(2).text
?br />
this.attributes(2).text
注意Q如果给定的下标大于属性d?出错,W一个属性的下标??/p>
四、baseName
含义Q返回有名字I间限制的基本名Q即不包括名字前~?/p>
语法Qobject.baseName
参数Qobject ── l点对象
CZQ当前结点的基本名:
this.baseName
五、childNumber
含义Q返回结点相对于同名同胞的序受?/p>
语法QchildNumber(object)
参数Qobject ── l点对象
CZQ假定XML文档l构如下Q?/p>
<x><y><z></z></y></x>
如果当前l点是zQ则childNumber(this)q回1Q而absoluteChildNumber(this)q回3?
六、dataType
含义Q设定或dl点的数据类型?/p>
语法Q设定结点的数据cd object.dataType=objValue
dl点的数据类?objValue=object.dataType
参数Qobject ── l点对象?br />
CZQ读取当前结点的数据cdQ?/p>
dtType=this.dataType
七、depth
含义Q指定结点出现在文档树上的深度,卌l点位于文档W几层,层l点位于W一层,根结点(即用"/"表示的结点)位于W?层?/p>
语法Qdepth(pNode)
参数QpNode ── l点对象
CZQ当前结点的深度Q?/p>
depth(this)
八、firstChild、lastChild
含义Q返回结点的W一个子l点Q或最后一个子l点Q?/p>
语法QpNode.firstChild
pNode.lastChild
参数QpNode ── l点对象
CZQ当前结点的W一个结点的名字Q?/p>
this.firstChild.nodeName
九、formatIndex
含义Q用指定的计数系l格式化提供的整数?/p>
语法QformatIndex(lIndex, bstrFormat)
参数Q?/p>
lIndex ── 整型数值或变量
bstrFormat ── 数据格式Q可选值有a、A、i、I??1Q以0打头的数值Ş式,如果要求固定长度的编号如0001?002则非常有用)?/p>
CZQ当前结点的大写|马数字~号Q?/p>
formatIndex(childNumber(this),'I')
十、formatNumber
含义Q以指定格式输出数倹{?/p>
语法QformatNumber(dblNumber, bstrFormat)
参数Q说明同formatNumberQ不同之处在于格式化的可以是数?/p>
CZQ对变量a的值格式化Z位小敎ͼ
formatNumber(a,'#.00')Q?/p>
十一、hasChildNodes
含义Q如果结Ҏ子结点则q回trueQ?1Q,否则为falseQ?Q?/p>
语法QpNode.hasChildNodes()
注意Q与此前介绍的函C同,此函数后必须带一个空括号?/p>
CZQ判断当前结Ҏ否有子结点:
this.hasChildNodes
十二、namespaceURI、prefix
含义Q返回结点名字空间的全局资源标识W(或前~Q?/p>
语法QpNode.namespaceURI
pNode.prifix
十三、nextSibling、previousSibling、parentNode
含义Q返回结点的下一个兄弟(或前一个兄弟、或l点的父l点Q?/p>
语法QpNode.nextSibling
pNode.previousSibling
pNode.parentNode
注意Q对根结点(?/"Q应用parentNodeҎ、对W一个孩子结点应用previousSiblingҎ、对最后一个孩子结点应用nextSiblingҎ均会D错误Q可通过此过关系q算W?=Q等于)?=Q不{于Q来判断一个结Ҏ否某一指定l点Q格式ؓpNode1 = pNode2或pNode2 != pNode2?/p>
十四、nodeName
含义Q返回元素、属性、入口的名字或其他类型结点的一个特定字W串?/p>
语法QpNode.nodeName
CZQ当前结点的名字Q?/p>
this.nodeName
十五、nodeType、NodeTypeString
含义Q返回结点的cd的数值Ş式(或字W串形式Q?br />
语法QpNode.nodeType ?pNode.nodeTypeString
q回|
十六、nodeTypedValue
含义Q以l点预定义的数据cdq回l点的倹{?/p>
语法QpNode.nodeTypedValue
CZQ假定当前结点的数据cd是fixed.14.4Q下例将以数D回结点的|而不是文本一个字W串Q?/p>
this.nodeTypedValue
十七、nodeValue
含义Q返回结点的文本?/p>
语法QpNode.nodeValue
注意Q该Ҏ不用于元素类l点Q可用于属性、CDATA、注释、文本等l点?/p>
CZQ当前元素第一个属性的|
this.attributes(0).nodeValue
当前元素内的文本Q假定该元素内只有文本,无其它元素,?lt;mark>text</mark>Q徏议多几ơ掌握其切的用法)?/p>
this.firstChild.nodeValue
十八、ownerDocument
含义Q返回包含该l点的文档的栏V?/p>
语法QpNode.ownerDocument
注意Q该Ҏ用于文档的根l点出错?/p>
十九、selectNodes
含义Q给定的样式匚w应用于当前结点ƈq回匚w的结炚w合?/p>
语法QpNode.selectNodes('pattern')
提示Qpattern的编写与<xsl:for-each>的select属性的值类|其中?/"开头表CZ文档的根出发搜烦Q以"http://"开头表遍历文档的所有结点;?.."开头表CZ当前l点的父l点开始;如果Ʋ从当前l点向下搜烦则不能有以上Ҏ字符打头?/p>
CZQ与当前l点同名的元素在其父元素内的个数Q?/p>
childNumber(this.selectNodes("../"+this.nodeName+"[end()]").item(0))
当前元素内名字ؓ"skill"的元素的个数Q?/p>
childNumber(this.selectNodes("skill[end()]").item(0))
二十、selectSingleNode
含义Q与selectNodescMQ不同的只返回匹配的W一个结炏V而不是结炚w合?/p>
语法QpNode.selectSingleNode('pattern')
CZQ与当前l点同名的元素在其父元素内的个数Q?/p>
childNumber(this.selectSingleNode("../"+this.nodeName+"[end()]"))
当前元素内名字ؓ"skill"的元素的个数Q?/p>
childNumber(this.selectSingleNode("skill[end()]"))
二十一、text
含义Q返回结点与它的子树内的文字内容?/p>
语法QpNode.text
CZQ整个文档内的文字内容:
this.ownerDocument.text
当前元素及其子树的文字内容:
this.text
二十二、xml
含义Q返回结点及其后代的XML表示?/p>
语法QpNode.xml
CZQ当前文档的XML内容Q?/p>
this.ownerDocument.xml
另有几个函数不作介绍Q列于其下以供参考,如感兴趣Q请讉Khttp://msdn.microsoft.com获取详细说明?/p>
formatTime(varTime, bstrFormat,varDestLocale)
formatDate(varDate, bstrFormat,varDestLocale)
apendChild(newChild)
definition
CloneNode
insertBefore(newChild, refChild)
parsed
removeChild(oldChild)
replaceChild(newChild, oldChild)
specified
transformNode(stylesheet)
transformNodeToObject(stylesheet,outputObject)
uniqueID(pNode)
含义Q计脚本表辑ּQ输Z个文本字W串?/p>
语法Q?br />
属性:
language ── 规定所用脚本语a的名字,可用的属性有"JavaScript"?JScript"?VBScript"?VBS"{,~省?JScript"?/p>
<xsl:script>
含义Q声明全局变量或定义函数?/p>
语法Q?br />
属性:?lt;xsl:eval>
CZQ?/p>
不知大家对于W四期《跟我学XML》中的例子是否还有印象?其中的XML文档q没有对历编P但输Z却加上了大写的罗马数字序受今天将再D一Eؓ复杂一些的例子Q?/p>
假如我们~写一份年l生产统计表Q其中需要小计一,常规的作法是事先其出来,现在不必了,我们可以只给出单统计,昄时再l计计一V请扑և《跟我学XML》的W四期,XML文g不必修改Q对XSL文g的修改如下:
说明Q?/p>
注意到执行结果的变化了吗Q黑体部分ؓd部分Q注意添加部分分Z部分Q?lt;xsl:script></xsl:script>必须|于</TABLE>之后Q切记?/p>
selectNodes() ── 是XMLDOMObject的一个方法,q回文档中所有满x件的l点的集合,条g?lt; xsl:for-each >和select属性的取值采用同L写法Q可以加{选、下标等限制Q如L一季度产量大于{于50的班l:
/document/report/q1[value() $ge$ 50]
以上写法q有一个更单的写法Q?/p>
//q1[value()$ge$50]
//表示从根l点出发遍历所有结点,L满条g的结点,如果文档内有同名但意义不同的l点则不能用此种ҎQ非不得已不使用。以此ؓ例,如果希望l计qM量,则可以下q字W串Ll点Q徏议用最后一U,此种描述精找到需要汇ȝ数据Q:
//*[value()$gt$0] ?//(q1|q2|q3|q4) ?/document/report/(q1|q2|q3|q4)
nextNode() ── q回l点集中的下一个结?/p>
Number() ── 提供的参数转换为数?/p>
下期介绍XSL函数2Q用?lt;xsl:script>?lt;xsl:eval>中,以及<xsl:if>?lt;xsl:when>的expr属性。徏议读者熟悉JavaScript、JScript、VBScript中至一U,否你能用XSL完成的工作将十分有限。由于篇q关p,此处不作详细介绍?/p>
我们q里不打就XML的DOM逐一详细阐述Q因完全可以写成一个篇q较多的教程Q我们先׃些常见的Ҏ作一些讨论,以期对DOM的对象方法有一个大致的了解?/p>
注:从本期开始,所有示例不再提供完整源代码Q如有不明白之处Q请仔细阅读前面七期、ƈ动手l手?/p>
一、end()
含义Q返回集合中最后一个元素?/p>
CZQ输出最后一份简?/p>
假定XML文g格式为:
…?lt;resume>?lt;/resume>…?lt;resume>?lt;/resume>…?/p>
相应XSL文g内容为:
二、index()
含义Q返回该元素在集合中的位|,q回值是一整数Q其中第一个元素返??/p>
CZQ返回前面三份简历?/p>
resume[index()$le$3]
注意Qindex()是与父元素相关的Q请看下例:
q回所?lt;x>中的W一?lt;y>
x/y[index()=0] 或x/y[0]
三、nodeName()
含义Q返回元素的名字Q即标记名?/p>
CZQ选择L元素Q假如其名字Q即标记名){于"name"Q?/p>
*[nodeName()='name'] ?*[name]
四、number()
含义Q将D{换ؓ数值Ş式,如果不是数值则q回I,要求参数?/p>
CZQ年?age)于30岁的人的?resume)Q?/p>
resume[number(age)$lt$30] ?resume[age$lt$30]
五、nodeType()
含义Q返回结点类型,l果为是数倹{以下是q回值列表:
六、value()
含义Q返回元素或属性的倹{?/p>
CZQvalue()是元素或属性的~省ҎQ以下表C是{hQ?/p>
name!value()="NAME" ?name="NAME"
@attr="attribute_value" ?@attr="attribute_value"
注:@是属性前~Q@attr表示是属性attr
七、attribute()
含义Q返回所有属性结点的集合Q等价于"@*"?/p>
CZQ寻找所有的resume元素Q满x件至有一个属性的gؓ"ABC"Q?/p>
resume[$any$attribute()='ABC'] ?resume[$any$@*='ABC']
L所有的resume元素Q满x件至有一个子元素有一个属性的gؓ"ABC"Q?/p>
resume[$any$*/attribute()='ABC'] ?resume[$any$*/@*='ABC']
八、comment()
含义Q返回所有注释结炏V?/p>
CZQ?/p>
resume[$any$comment()='希初的?]
表示L含有注释语句Q?lt;!--希初的?->?lt;resume>元素?/p>
九、cdata()
含义Q返回所有CDATAcd的结点的集合?/p>
CZQ?/p>
resume[$any$cdata()='希初的?]
表示L含有下述语句Q必L直接子结点)<![CDATA[希初的历]]>?lt;resume>元素?/p>
十、node()
含义Q返回当前上下文环境中除根结点和属性结点以外的所有结点的集合Q等价于Q?/p>
"*|pi()|comment()|text()"
CZQ寻找所有元素resumeQ其最后一个结点的名字?skill"Q?/p>
resume[node()[end()]!nodeName()='skill']
L所有resume元素的第一个结点:resume/node()[0]?/p>
十一、textnode()
含义Q返回所有文本类型的l点的集合?/p>
CZQ寻找每一个p元素的第二个文本l点Q?/p>
p/textnode(1) ?p!textnode(1)
十二、text()
含义Q返回所有表C文本字W串的结点的集合Q等价于"cdata()|textnode()"?/p>
本期的内容就介绍xQ另有一个函数date()在本人的机器上一试就发生错误使浏览器自动关闭Q还有一个函数pi()本h未扑ֈ适当的应用方法,׃介绍了,下期讲q如何XSL中用脚本?/p>
CZ一Q?/p>
从个人简历中Lhh"WEB开?技能的人的姓名与E-Mail。假设文档结构如下所C:
说明Q?/p>
1.[ ] ── 表示选择条gQ只有满x件的个h历才被显C?/p>
2.$any$ ── ׃每个人有多种技能,故加$any$作ؓ前缀Q以使每个h所有技能都能被比较?/p>
3.skill='WEB开? ── {选条件?/p>
CZ二?/p>
仍上面的XML文档ZQ如果欲选择1977/1/1之前出生的h的姓名、技能与E-MailQ相应的XSL文档l构如下Q假定生日格式ؓyyyy/mm/ddQ:
说明Q?/p>
1.birthday $lt$ '1977/1/1' ── 搜烦条gQ在此处使用"< "会错误,故?$lt$"表示于?/p>
2.skill [0] ── 表示选择skill的第一V?/p>
3.skill [index()>0] ── 表示选择skill的第二项以后Q包括第二项Q的目?/p>
4.xsl:value-of select="." ── 表示选择当前标记的倹{?/p>
怿大家应该注意刎ͼ在前面以及本ơ的例子中出C一些函敎ͼ如index()、formatIndex()、childNumber()Q也许大家还不完全明了其中的含义吧?敬请x下一课?/p>
<xsl:when>
语法Q?br />
<xsl:otherwise>
语法Q?lt;xsl:otherwise>
属性:无,在一个多选测试中Q如果没有不满<xsl:when>规定的条Ӟ如果在最后有此标讎ͼ则输出此标记中的内容?/p>
CZQ?/p>
此处以学生成l单ZQ要求按成W的高低给ZUQ?>85Q、一般(70~85Q、及|60~69Q、不及格Q?lt; 60Q,而不是显C分数。其中成l单的XML文档(文g名:grade.xml)如下Q?br />
为实现按分数分等U显C,其XSL文档Q文件名Qgrade.xslQ内容如下:
XSL中的IFQ首先,介绍XSL元素<xsl:if>的语法结构:
语法Q?br />
expr ── 脚本语言表达式,计算l果????Q如果结果ؓ"?Q且通过testQ则在输Z昄其中内容Q可省略此项属性)?
language ── expr属性中表达式的脚本语言cdQ其取gHTML标记SCRIPT的LANGUAGE属性的取值相同,~省?JScript"?br />
test ──源数据测试条件?
CZQ?
此处以一份报表ؓ例,文g名ؓreport.xmlQ其内容如下Q?
说明Q?/p>
q1|q2|q3|q4 ── 标记q1、q2、q3、q3均用此模板确定输?/p>
$le$ ── 是关p运符中的"于{于"Q其它关pL于Q?lt$Q、大于($gt$Q、大于等于($ge$Q、等于($eq$Q、不{于Q?ne$Q等?/p>
. ── 表示引用当前标记?/p>
[ ] ── 表示{选,只有满{选条件的标记才能被选取?/p>
value() ──XSL函数Q其他常用XSL函数有text()、end()、index(){?
下期Q我们将学习XSL的另外三个元素,可对同一数据q行多次试Q根据不同条件生相应输出?/p>
前面我们学了<xsl:for-each>?lt;xsl:value-of>{,可以用它们对XML数据实现单的格式化输出,但如果遇到比较复杂的XML格式输出Q将XSL按照要求依次写下来的话,一是设计困难,可扩展性差Q不利于人员之间的分工协作;另则Q可修改性很差,可能会出现牵一发而动全军的情况,不利于维护。程序中模块化设计逐步l化的方法在q里得到了应用!
XSL模板XSL的设计细化成一个个模板Q块Q,最后再这些模板(块)l合成一个完整的XSLQ好比船与集装箱Q我们不是将所有的货物一件g地堆hQ而是装在各自的集装箱中,然后再在船上这些集装箱堆放h。这U方法可以你先从整体上考虑整个XSL的设计,然后一些表现Ş式细化成不同的模块,再具体设计这些模块,最后将它们整合在一Pq样Q将宏观与微观结合v来,W合Z条理化、规范化要求?/p>
装集装箱Q-书写模板Q块Q:<xsl:template>
语法Q?br />
match ── 定什么样的情况下执行此模ѝ作ZU简化的说明Q在此处使用标记的名字;其中最上层模板必须match设ؓ"/"?/p>
language ── 定在此模板中执行什么脚本语aQ其取gHTML中的SCRIPT标记的LANGUAGE属性的取值相同,~省值是Jscript?/p>
<xsl:template>用match属性从XML选取满条g的节点,征对q些特定的节点Ş成一个特定输出Ş式的模板?/p>
吊集装箱上船Q-调用模板Q块Q:<xsl:apply-templates>
语法Q?/p>
属性:
select ── 定在此上下文环境中应执行什么模板,即选取?lt; xsl:template >标记建立的模板(块)?/p>
order-by ── 以分P;Q分隔的排序标准Q通常是子标记的序列?/p>
CZQ?/p>
以个人简历ؓ例,Z于处理我们希?技?中每一w用标记对<skill></skill>括v来,有多项技能就有多个q种标记对,l过修改后的个h历XML文档内容如下Q?br />
注意Q如果XML文档中不同标记有同名的子标记Q在为其~写模板Ӟ应把父标C为其前缀Q格式ؓQparent_mark/child_markQ。模板文件必L一个根模板Q其属性match?/"?/p>
参考微软的"XSL开发者指?Q我们大致可模式语a分ؓ三种Q?/p>
选择模式Q?br />
<xsl:for-each>?lt;xsl:value-of>?<xsl:apply-templates>
试模式Q?br />
<xsl:if> ?lt;xsl:when>
匚w模式Q?br />
<xsl:template>
我们现在分别对之进行介l?br />
一?选择模式
选择模式语句数据从XML中提取出来,是一U简单获得数据的ҎQ这几个标记都有一个select属性,选取XML中特定的l点名的数据?br />
1?lt;xsl:for-each>
如在XML中有q样的数?
2?lt;xsl:value-of>
<xsl:for-each>模式只是选取节点Qƈ没有取出节点的|好比猴子只是爬到了树的某个枝q上Q那么就?lt; xsl:value-of >来摘"胜利果实"吧!
语法Q?br />
<xsl:value-of select="pattern">提取节点的?br />
属性:
select用来与当前上下文匚w的XSL式样。简单的Ԍ如果要在XSL文档某处插入某个XML标记Q假定是xml_mark标记Q的内容Q可用如下方式表C:
随着Internet的发展,来多的信息进入互联网Q信息的交换、检索、保存及再利用等q切的需求HTMLq种最常用的标记语a已越来越捉襟见肘。HTML数据内容与表现融ؓ一体,可修Ҏ、数据可索性差Q而XML借鉴了HTML与数据库、程序语a的优点,内容与表现分开Q不仅ɋ索更为方便,更主要的是用户之间数据的交换更加方便Q可重用性更强?/p>
XML是一U元标记语言Q没有许多固定的标记QؓWEB开发h员提供了更大的灵zL。当我们使用HTMLӞ标记只是单的表示内容的显CŞ式,而与表示的内Ҏ有Q何关联,为文档的q一步处理带来极大的不便。比如要表示个h历,用HTML的表C方式如下:
在这里,我们无法从标记TH、TD得知其内容表CZ么,如果用XMLQ相应的文档Q文件名Q个人简?xmlQ就可写成如下Ş式:
说明Q?/p>
version──规定了XML文档的版本,此处只能?.0Q?/p>
encoding── 此处规定了XML文档的编码类型,此处取gؓ"GB2312"Q也是"体中??/p>
Ҏ两例Q用XML我们可以做到自定义标讎ͼ用标记表明内容的含义。这样在Internet上交资料时Qؓ用计机处理文档提供了极大的方便Q同时我们阅L文g时也不会被一大堆格式弄得晕头转向?/p>
然而,׃XMLq没有ؓ标记规定昄方式Q如果我们在游览器中查看以上两个文档Q徏议用IE5.0或更新版本)Q我们将看到xml文档q没有以诸如表格的方式来昄。难道我们就不能像HTML一hC文档吗Q回{是否定的。以个h历ؓ例,需要另Z个格式文件说明各个标记的昄方式Q其内容如下Q假设文件名为resume.cssQ:
说明Q?/p>
以上均ؓCSS样式Q徏议读者参考有兌料熟悉CSSQ在以后学习中必ȝ刎ͼ此处׃幅关系不作介绍。徏立文件resume.css后,在个人简?xml文g的第一行后d以下文字Q?br />
说明Q?/p>
此处表示引用一个外部CSS样式文gQ其中type规定样式cdQ可取gؓtext/css或text/xslQ,href规定文g路径?/p>
保存文gQ再以IE5.0打开文g。怎么P格式有些不一样吧。好象还不o人满意,文档内容是清CQ但昄效果比HTML~写的文档就差得多了QXML~写的文档就只能以这U方式显C吗Q!
提示Q?/p>
1. Z更好的理解与掌握XMLQ徏议大家熟悉HTML 4.0与CSS 2.0语法Q掌握JavaScript、VBscript中至一U;~程l验、对数据库理ZSQL的了解均能大家在学习XML时获益?/p>
2. XML文档中标记必L对出玎ͼ如果是空标记也必L前加"/"的同名标记结束,或用此U文?lt;xml_mark/>表示I标记?/p>
3. XML以及下面要介绍的XSL文档Q属性值必ȝ双引P"Q或单引P’)括v来?/p>
4. XML文档必须是良构的QXSL文档也是XML文档中一U)Q也是说标记必Ll束标记、标记可以嵌套但不可交叉Q如Q?br />
<outer><inner></inner><inner/></outer>
是合法的Q而下面的形式
<outer><inner></outer></inner>
则是错误的。如果XML文档在浏览时出错Q多半是q反了上面提到的规则?br />
SOAPQ简单对象访问协议)定义了客h与服务器之间传递的消息。消息采?XML 格式。SOAP 独立于^台、编E语a、网l和传输层?/p>
q次做的目中需要提供WebService服务Q没话说Q由于是PHP的项目,首先按照习惯用了NuSOAPQ结果让我郁闷了好久Q程序返回的是一个数l,但是用print_r()打印出来是空的,用count()看了一下大ؓ1Q郁闷ing。看了一下response数据是存在的啊。又对照了一下以前做的SOAPQ是在PHP4上的Q,两个response有点不同Q这才反应过来是PHP5跟PHP4的版本不一栗?/p>
打开php.iniQ找到扩展模块那部分Q把soap的模块加载上Q又重新写了一下Server端和Client端,l箋试。L出现“looks like we got no XML document”的error。难道是用法错了Q手头正好有本《PHP5 Power Programming》找到SOAP的地方,没找到问题,又跑到zend的官方网站上看了一下SOAP的介l和CZQ?a >http://www.zend.com/php5/articles/php5-SOAP.php?out=dynamicwebpagesQ,没错啊。去Google搜烦q个错误Q最后还是连Czend的一个blog上(http://www.zend.com/php5/articles/php5-SOAP.php?article=php5-SOAP&kind=php5&id=5085&open=1&anc=0&view=1Q,前半部分跟上面那个是一LQ直接蟩q,看下面的CommentQ发现好多h都遇Cq个问题Qh提到是在PHP开始标{之前存在blank characterQ可我的没有啊,我的有个require_once("mainfile.php")Q把q句注释掉以后就没问题了Q又l箋Ҏmainfile.phpq踪下去Q发现是在类的文件中PHPl束标签之后有blank characterQ删除掉没问题了?/p>
在zend上的comments里还有h提到是XML文g的编码问题,q个我没有测试。终于搞定了q个问题Ql写接口Q哎…?/p>
郁闷本来x全部代码贴上来,l果排版会有问题Q还是脓些重要的吧!
Server端: