标签存档: XML

XSL中的运算符与变量名

昨天在写XSL模板的时候,在模板中使用了一个变量,结果在调试的时候却怎么也不行,我的变量名是$ItemCount,然后在模板中使用了这个变量 :

  • <xsl:value-of select=”Tag[position() = $ItemCount-1]” />

在调试时却总是提示“无法解析到变量或参数 ‘ItemCount-1’的引用。变量或参数可能没有被定义,或它可能不在范围内。”,我就奇怪了,这名字明明是对的,怎么会有错呢,然后就又在变量定义的地方把变量名给复制过来,看看还是不是会出错,结果还是一样的错误。

这下郁闷了,懒得伺候了,把东西扔一边,玩去了~

今天想到这个事,再不行这个模板总是要写完的,于是又开了EditPlus,找到那一句,就在想怎么改它,突然脑子里来了一点点灵光,在减号的两边各加了一个半角空格,Firefox里打开,bingo!正确执行。

在解决了这个问题之后才想到,短划线也就是“-”在XML里是符合命令规范的,也就是说,我在写成“$ItemCount-1”的时候,XSL Parser 把“$ItemCount-1”认为是一个变量,而不会认为是一个表达式,因此,就会提示找不到变量,出错。

找到问题的原因所在,就好解决了,直接把减号给独立出来:

  • <xsl:value-of select=”Tag[position() = $ItemCount – 1]” />

解决问题,继续写模板。

XML+XSL+CSS+ASP打造留言簿

前段时间无意间看到一个博客的RSS可以用XSL格式输出并且能在Firefox里浏览,想到自己以前写的一个XML留言簿因为不兼容Firefox所不了了之了,现在看到他的能在Firefox浏览就觉得很好奇,看了一下代码,一句一句的比对,最后终于找到了原因,也就把这个留言簿给完成了。因为是一个简单的XML留言簿,所以取名SXGB(Simple XML GuestBook)。

查看留言本演示,管理密码为test:

首先定义留言簿的XML文档的格式。作为一个留言簿,不需要太复杂的内容,于是我就给留言内容分为3个部分:留言者姓名、留言者主页和留言内容。另外,一个留言簿还需要有使用者的一些信息,包括用户名和用户主页。再有,在留言比较多时还需要分页信息。大致结构完成后就可以开始写XML文档模板了。

XML文档根元素定义为gbook

XML文档模板gbook.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<!– DTD file –>
<!DOCTYPE gbook SYSTEM “sxgb.dtd”>
<!– XSL file –>
<?xml-stylesheet type=”text/xsl” href=”gbook.xsl”?>
<gbook>
<!– 留言簿相关信息 –>
<info>
<!– 用户名 –>
<user>HotHeart</user>
<!– 用户主页 –>
<home>http://www.xujiwei.cn</home>
<!– 分页信息,分别为目前所在页,总页数,上一页,下一页 –>
<pagenow>1</pagenow>
<pagetotal>1</pagetotal>
<pageprev>1</pageprev>
<pagenext>2</pagenext>
<!– 是否已经登陆,用来处理是否显示登陆框 –>
<logined>NO</logined>
</info>
<!– 留言列表 –>
<messages>
<!– 一个留言 –>
<message>
<!– 留言ID –>
<id>1</id>
<!– 留言者姓名 –>
<username>Admin</username>
<!– 留言时间 –>
<time>2005-08-09 12:00</time>
<!– 留言者主页 –>
<homepage>http://www.xujiwei.cn/</homepage>
<!– 留言内容 –>
<content><![CDATA[ 留言内容 ]]></content>
</message>
</messages>
</gbook>

要注意在引用XSL时不能用

<?xml:stylesheet type=”text/xsl” href=”gbook.xsl”?>

xml和stylesheet之间应该用一杠(-)而不能用冒号(:),在Firefox里是不支持用冒号的。

一个好的XML文档,除了要有结构性,还应该要有有效性,所以在XML文档的一开头就定义了文档类型定义(DTD) sxgb.dtd,下面就来把这个文档类型定义给完成。因为已经设计好留言簿XML文档的结构,所以写出DTD是很方便的。

继续阅读 »

AJAX初体验之上手篇

AJAX是这两年蛮热的东西,我也凑凑热闹,前些天去找了些教程学学,下面就按整个处理过程把自己学的东西写写,不过,因为是初学,所以有错误就请见谅啦,也欢迎指正,vipxjw#163.com。

PS.写完了之后看了下,结果再次验证自己写教程真是乱得可以,东说一块西说一块,条理不太清楚的说:)。

1.创建 XMLHttpRequest 对象

现在的浏览器有很多种,创建 XMLHttpRequest 的方法也不相同,所以为了兼容各种浏览器,在创建 XMLHttpRequest 时也应该考虑到各种浏览器的情况。目前主流的浏览器在Windows下有IE、Firefox及Opera,所以我们写的代码要尽量兼容这几个浏览器。在参考了一些资料后,我用下面的方法来创建 XMLHttpRequest 对象:

// 先定义一个变量,并赋初值为 false,方便后面判断对象是否创建成功
var xmlObj = false;
// 使用 try 来捕获创建失败,再换个方法来创建
try {
// 在 Mozilla 中使用这种方式来创建 XMLHttpRequest 对象
xmlObj=new XMLHttpRequest;
}
catch(e) {
try {
// 如果不成功,那么尝试在较新 IE 里的方式
xmlObj=new ActiveXObject(“MSXML2.XMLHTTP”);
}
catch(e2) {
try {
// 失败则尝试使用较老版本 IE 里的方式
xmlObj=new ActiveXObject(“Microsoft.XMLHTTP”);
}
catch(e3) {
// 还是失败,那么就认为创建失败……
xmlObj=false;
}
}
}
// 如果创建 XMLHttpRequest 对象失败,那么提醒访问者该页面可能无法正确访问
if (!xmlObj) {
alert(“XMLHttpRequest init Failed!”);
}
2.使用 XMLHttpRequest 来获取 XML 文档
在用 XMLHttpRequest 来获取 XML 需要注意这个文档必需和自己在同一个域中,我的理解是同一个域名之下,或者同一目录之中,如果不是就会出现“拒绝访问”的错误。在本地高度时,也必需运行一个 Web 服务器,而不能直接在浏览器里打开这个网页。

// 使用 open 方法来打开一个请求,这个方法有3个参数,分别是请求方式,请求文件的URL及同步方式(?不是很清楚具体叫什么来的:)
// 请求方式可以是 GET,POST,HEAD中的一种,因为我要获取文件,所以用 GET
// 请求文件的URL,直接用相对路径即可
// 同步方式,表示请求发出后是等待回应(false)还是继续执行下面的代码(true),即所谓异步了。AJAX的第一个A就是表示异步了,所以这里用 true
xmlObj.open (“GET”, “sample.xml”, true);
// 因为使用异步方式所以要在 XMLHttpRequest 对象的状态改变时做相应的处理
xmlObj.onreadystatechange=function() {
// 如果 XMLHttpRequest 的状态为4,应该是ready来的,那么继续处理
if(xmlObj.readyState==4) {
// 需要判断返回状态是否为200 OK,有些情况如文件不存在,就为返回404
if(xmlObj.status==200) {
// 一切OK,调用处理过程
DoMyXML();
}
}
}
// 发送请求,因为是GET,所以send的内容为null
xmlObj.send(null);

3.用ASP来创建XML文档3.用ASP来创建XML文档
为了动态显示的需要,就要用到动态网页了,我用的是ASP。

<%
‘ 修改头标识指明这是一个XML文档
Response.ContentType=”text/xml”
‘ ……
strXML=”<?xml versin=””1.0″” encoding=””gb2312″”?>”
‘ 这里就按XML的要求来输出数据库里的内容了
strXML=strXML&”…..”
‘ ……
Response.Write(strXML)
%>

4.处理XML文档
在获取了XML文档之后,就要从中获取需要的东西了,假如我从服务获取了下面的XML文档:

  • <?xml version=”1.0″ encoding=”gb2312″?>
  • <root>
  • <item>
  • <title>AJAX Study</title>
  • <content>Study AJAX</content>
  • </item>
  • </root>

我要的是title及content的内容,那么可以像下面这样做:

  • function DoMyXML() {
  • var xmlDoc,items,title,content;
  • // 先从XMLHttpRequest对象中得到XML文档
  • xmlDoc=xmlObj.responseXML;
  • // 再得到items
  • items=xmlDoc.getElementsByTagName(“item”);
  • // 最后根据TagName来获取想要的内容
  • // 如果XML文档里有多个item,可以用数组的下标来表示第几个
  • title=items[0].getElementsByTagName(“title”)[0].firstChild.data;
  • content=items[0].getElementsByTagName(“content”)[0].firstChild.data;
  • }

好了,现在已经得到我想要的东西,可以把它们显示出来了。

5.输出处理结果

先假定有一个如下的HTML文档用来显示想要输出的内容:

  • <html>
  • <head>
  • <title>AJAX Study</title>
  • </head>
  • <body>
  • <div id=”mydisplay”></div>
  • </body>
  • </html>

  • 这里定义了一个ID为mydisplay的DIV容器用来显示输出内容,好了,再转到JS:
    • //…接DoMyXML;
    • //content=items[0]…..;
    • var strHTML;
    • // 先组织好要显示的内容
    • strHTML=”Item title: ” + title + “<br />Item content: ” + content;
    • // 获取目标容器,再设置它的innerHTML为要显示的内容
    • document.getElementById(“mydisplay”).innerHTML=strHTML;

  • OK,这些差不多是编写AJAX程序的基础,具体用就看个人发挥了,当然AJAX并不只这些,还有如果POST方法发送数据等,不过这个还没学过,所以只能讲这些了^_^。还是那句话,因为是初学,有错误在所难免,欢迎指正。
  • [JavaScript] 静态的动态续篇之来点XML

    在搞定了基本的伪动态之后,我马上把它应用到了网站,但随后就发现了一个问题:我如何来管理新闻列表呢?要是让我在每次要加新闻时去修改源文件然后再上传我可是千万个不愿,不仅麻烦而且容易出错,懒人怎么能可以这么做。动动脑子,于是想到了用XML,这个早已存在,但近些年才流行起来的技术。

    在HTML里,可以使用数据岛来使用XML数据,一个使用方法就是在HTML里加入一句:

    <xml id=”data”>

    <!– 在此为XML数据 –>

    </xml>

    这样,就可以在HTML里使用XML提供的数据。不过,这样还是显得麻烦了,还是要上传整个文件,那么用方便点的吧~~

    <xml id=”data” src=”data.xml”/>

    这样处理之后,我就可以只用修改一个XML文件然后上传到服务器了。

    接下来,就是搞定在客户端对XML数据的处理了~~

    首先,我得设计一个新闻的数据结构。这个简单,毕竟在列表时只需要用到新闻的标题和时间,但为了链接,需要加上一个ID,结果如下:

    <newslist>

    <news>

    <id>1</id>

    <title>第一个新闻</title>

    <date>2005-11-16</date>

    </news>

    </newslist>

    数据结构搞定了,继续!

    在客户端对数据处理当然首选JavaScript了,再么这篇文章讲的也是用JavaScript来实现伪动态。

    在JS里,对数据岛的访问可以使用记录集:

    var rs=data.recordset;

    这个记录集的使用方法和ASP中类似,这下方便我了:),可以很方便地实现新闻的列表及链接了~在显示新闻,还需要显示的是上一条新闻的标题及下一条新闻的标题,而且显示新闻列表时,就不需要显示上一条及下一条新闻了。于是我放了两个层分别用来显示新闻和上一条及下一条新闻的信息,并在需要的时候设置是否显示。其中newsmain用来显示新闻或者新闻列表,newspage用来显示上一条及下一条新闻的信息。接着把对应ID的新闻存为网页文件,在显示时使用iframe嵌入。

    先写个函数来从网址中获取新闻ID,这个在前一篇文章已经讲过,拿来用~~

    function getid() {

    var str,len,pos,id,fn;     // 定义一些变量

    str=top.window.location.href;    //获取当然文件地址

    len=str.length;     // 得到地址长度

    pos=str.indexOf(“?id=”,0);   // 得到”?id=”的起始地址

    // 判断是否存在”?id=”

    if(pos>0) {

    id=str.substring(pos+4,len);   // 获取ID

    return eval(id);  // 返回数值类型的ID,方便处理

    }

    else {

    return 0;  // 错误参数,返回0,显示新闻列表

    }

    }

    再来个函数处理进入页面时执行什么动作,是显示新闻列表还是显示相应ID的新闻

    function showmain() {

    var id;

    id=getid();  // 获取新闻ID

    // 是 0 则显示列表

    if(id>0) {

    rs.absoluteposition=id;  // 设置游标到指定的新闻

    shownews(id); // 显示新闻

    }

    else {

    showlist();   // 显示新闻列表

    }

    }

    显示新闻列表的函数

    function showlist() {

    var ss=””;  // HTML

    var i;  // 循环计数器

    rs.movefirst();  // 移动到第一个记录

    // 循环读取新闻记录

    for(i=0;i<rs.recordcount;i++) {

    ss=ss+”<font color=#800000>·</font><a href=’javascript:shownews(“+rs(“id”)+”)’>”+rs(“title”)+”</a>&nbsp;(“+rs(“date”)+”)<br/>”;  // 添加一个新闻

    rs.movenext();  //移动到下一条一新闻

    }

    document.all.newsmain.innerHTML=ss;  //在新闻显示区输出新闻

    document.all.newspage.style.visibility=”hidden”;  // 显示新闻列表时,不显示前后新闻的信息

    }

    显示指定的新闻,并显示前后新闻的信息

    function shownews(id) {

    var ps;  // 用于存放前后新闻的信息

    document.all.newsmain.innerHTML=”<iframe class=’news_main’ frameborder=’0′ src=’news/”+id+”.htm’/>”;  // 用iframe来显示新闻

    document.all.newspage.style.visibility=”visible”;  // 使前后新闻信息可见

    rs.absoluteposition=id;  // 将记录游标移动到当前新闻

    // 如果ID小于1说明是第一条记录,上一篇新闻就是“没有了”:)

    if(id<=1) {

    ps=”上一篇:没有了”;

    }

    // 否则就显示上一篇新闻的标题

    else {

    rs.moveprevious();  // 记录游标向前移动

    ps=”<a href=’javascript:shownews(“+(id-1)+”)’>上一篇:”+rs(“title”)+”</a>”;  // 显示前篇新闻信息

    rs.movenext();  // 恢复记录游标

    }

    ps=ps+”&nbsp;”;  // 在两个信息之间插入一个空格

    // 如果ID大于记录总数说明这是最后一个新闻了~

    if(id>=rs.recordcount) {

    ps=ps+”下一篇:没有了”;

    }

    // 否则显示下篇新闻的标题

    else {

    rs.movenext();  // 记录游标向前移动

    ps=ps+”<a href=’javascript:shownews(“+(id+1)+”)’>下一篇:”+rs(“title”)+”</a>”;  // 显示下篇新闻的标题

    rs.moveprevious();  // 恢复记录游标

    }

    document.all.newspage.innerHTML=ps;  // 显示前后新闻标题~

    }

    好了,到底算是基本完工了~具体使用可以这样来:

    在head区加入XML数据岛

    <head><xml id=”data” src=”newslist.xml”/></head>

    接着在body的onload事件里执行showmain()

    <body onload=”showmain()”>

    还需要在body里加入两个层用于显示信息

    <div id=”newspage”></div>

    <div id=”newsmain”></div>

    完工!

    不过,我所用的方法也有不完善的地方,如新闻列表的ID必须保证顺序排列且不能有缺漏,因为在使用记录集时用到了绝对定位,还有其他等等。我写文章比较烂,所以:欢迎指正批评^-^!也欢迎大家我交流经验心得等,我的mail是vipxjw@tom.com。