使用Javascript和PHP对服务端XML文档进行操作

编辑工具与测试环境

netbeans 7.2.1

主要用来创建一个php项目,用于编辑php程序。

webstorm 6

主要用来方便javascript代码的编写工作。

xampp 1.8.1

主要需要使用其中的apache服务器。

chrome 26.0.1386.0

用来调试javascript代码

代码

index.html

<html>
  <head> 
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' /> 
    <title>AJAX with PHP: Quickstart</title>
    <link rel=stylesheet href="css/mystyle.css" type="text/css">
    <script type="text/javascript" src="js/myutil.js"></script>
    <script type="text/javascript" src="js/quickstart.js"></script>
  </head>
  <body>    
    <div>
        <div id="xmltable">

        </div>
        <div class="getxml">
            <input type="button" οnclick="getXmlFromPhp()" value="获取XML文档" />
        </div>
    </div>
    <div>
        <div class="editxml">
            <table border="1" class="fancytable" id=table2>
                <tr class="headerrow">
                    <td>CD专辑名</td>
                    <td>表演者</td>
                    <td>国家</td>
                    <td>发行公司</td>
                    <td>售价</td>
                    <td>出版年份</td>
                </tr>
                <tr class="datarowodd" id="editform" name="editform">
                    <td><input type="text" id="title" name="title"/></td>
                    <td><input type="text" id="artist" name="artist"/></td>
                    <td><input type="text" id="country" name="country"/></td>
                    <td><input type="text" id="company" name="company"/></td>
                    <td><input type="text" id="price" name="price"/></td>
                    <td><input type="text" id="year" name="year"/></td>
                </tr>
            </table>
        </div>
        <div>
            <input type="button" οnclick="appendRecord()" value="添加记录" />
            <input type="button" οnclick="deleteRecord()" value="删除记录" />
        </div>
    </div>
  </body>
</html>

js/myutil.js中的函数

函数:createXmlHttpRequestObject()
//获取XMLHttpRequest对象
function createXmlHttpRequestObject(){
    var xmlhttp;
    //IE
    if(window.ActiveXObject){
        try{
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }catch (e){
            xmlhttp = false;
        }
    }
    //Mozilla或其他browsers
    else{
        try{
            xmlhttp = new XMLHttpRequest();
        }catch (e){
            xmlhttp = false;
        }
    }
    if (!xmlhttp){
        alert("实例化XMLHttpRequest对象出错.");
        return xmlhttp;
    }
    else
        return xmlhttp;
}
函数:isnull()
//判断子节点是否为空
function isnull(obj)
{
    var nodevalue = "";
    if(obj.childNodes[0] != null)
    {
        nodevalue =obj.childNodes[0].nodeValue;
    }
    return nodevalue;
}
函数:xml2string(node)
function xml2string(node) {
    if (typeof(XMLSerializer) !== 'undefined') {
        var serializer = new XMLSerializer();
        return serializer.serializeToString(node);
    } else if (node.xml) {
        return node.xml;
    }
}

js/quickstart.js中的函数

变量
//保存XMLHttpRequest对象引用
var xmlHttp = createXmlHttpRequestObject();
//保存鼠标点击的表格table1的当前一行记录对应的HTML元素tr的id属性的值
var currentRecord;
//用于保存XML的DOM对象
var orderDoc;

函数:getDataByid(number)

//根据编号获取数据
function getDataByid(number){
    //获取number序号的CD元素节点的所有子元素节点的值
    var title =isnull(orderDoc.getElementsByTagName("TITLE")[number]);
    var artist =isnull(orderDoc.getElementsByTagName("ARTIST")[number]);
    var country =isnull(orderDoc.getElementsByTagName("COUNTRY")[number]);
    var company = isnull(orderDoc.getElementsByTagName("COMPANY")[number]);
    var price =isnull(orderDoc.getElementsByTagName("PRICE")[number]);
    var year =isnull(orderDoc.getElementsByTagName("YEAR")[number]);

    var test = number%2;
    var std ="";
    //根据number的奇偶性添加,表格记录行
    if(test == 1) {
        std='<tr id='+'"'+ (number+1) +'"' + 'class="datarowodd">' +
            '<td>'+(title)+'</td><td>'+(artist)+'</td><td>'+(country)+'</td>' +
            '<td>'+(company)+'</td><td>'+(price)+'</td><td>'+(year)+'</td>' +
            '</tr>';
    }else if(test == 0){
        std='<tr id='+'"'+ (number+1) +'"' + 'class="dataroweven">' +
            '<td>'+(title)+'</td><td>'+(artist)+'</td><td>'+(country)+'</td>' +
            '<td>'+(company)+'</td><td>'+(price)+'</td><td>'+(year)+'</td>' +
            '</tr>';
    }
    return std;
}

函数:getContent()
/*
获取XML文档树中所有CD元素节点,并以HTML表格形式保存
 */
function getContent(){
    var stringsss = "";
    //获取CD元素节点的个数
    var items=orderDoc.getElementsByTagName("CD").length;
    //添加HTML表格,以及表格标题行
    stringsss+='<table border="1" class="fancytable" id=table1>' +
        '<tr class="headerrow">' + 
        '<td>CD专辑名</td><td>表演者</td><td>国家</td>' + 
        '<td>发行公司</td><td>售价</td><td>出版年份</td></tr>';
    //将每一个CD元素节点内容作为表格的一行记录
    for(i=0;i<items;i++){
        stringsss+=getDataByid(i);
    }
    //添加HTML表格结束标签
    stringsss+='</table>'
    //在HTML文档中的id="xmltable"元素内容中添加stringsss字符串,即表格的HTML代码串。
    document.getElementById("xmltable").innerHTML = stringsss;
    //为表格的每行添加onclick事件处理方法
    addTrEvent();
}
函数:getXmlFromPhp()
/*
构造并发送HTTP请求,请求服务器发送XML文档
 */
function getXmlFromPhp(){
    //判断XMLHttpRequest对象是否空闲
  if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0)
  {
    xmlHttp.open("GET", "sendXML.php", true);  
    //指定处理服务器响应内容的方法
    xmlHttp.onreadystatechange = recvServerXml;
    //向服务器发送请求
    xmlHttp.send(null);
  }else{
      alert("XMLHttpRequest对象忙!");
      setTimeout('getXmlFromPhp()', 1000);
  }
}
函数:recvServerXml()
/*
处理服务端发送来的XML文档内容
用来根据接收到的XML文档,生成HTML表格代码
 */
function recvServerXml(){
    //当传送完成才继续
  if (xmlHttp.readyState == 4){
    //状态200表示传送成功完成
    if (xmlHttp.status == 200){
      //提取从服务器返回的XML文档
      xmlResponse = xmlHttp.responseXML;
      //将获取的XML文档DOM树结构对象赋值给全局变量orderDoc,以备之后使用
      orderDoc = xmlResponse;
      //构造HTML表格
      getContent();
    } 
    //如果返回一个非200的HTTP状态,则表示出错
    else{
      alert("在访问服务器时出现错误: " + xmlHttp.statusText);
    }
  }
}
函数:saveXmlToPhp()
/*
构造并发送HTTP请求,将修改的XML DOM对象发送给服务器端保存
并将新的DOM对象返回,以便更新客户端。
 */
function saveXmlToPhp(){
    if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0)
    {
        xmlHttp.open("POST", "saveXML.php", true);
        //将XML DOM对象转换成字符串
        var xmlstr = xml2string(orderDoc);
        //设置本次请求的结果处理方法
        xmlHttp.onreadystatechange = recvServerXml;
        //将XML文档序列化字符串作为参数发给服务器
        xmlHttp.send(xmlstr);
    }else{
        alert("XMLHttpRequest对象忙!");
        setTimeout('saveXmlToPhp()', 1000);
    }
}
函数:appendRecord()
/*
在本地的XML DOM对象中添加一个新的CD子节点
 */
function appendRecord(){
    //对空白编辑框的计数
    var emptyCount = 0;
    //循环检查table2中的文本编辑框,是否为全空,如果全为空则退出appendRecord()
    for(var i=0; i<6;i++){
        if(document.getElementById("table2").getElementsByTagName("input")[i].value == ""){
            emptyCount++;
        }
    }
    if(emptyCount >= 6){
        alert("至少有一个记录项不为空");
        return;
    }
    //保存CD元素的所有子元素名,以备循环创建子节点之用
    var nodeNameArray = new Array("TITLE","ARTIST","COUNTRY","COMPANY","PRICE","YEAR");
    //获取根元素节点
    var root = orderDoc.documentElement;
    //获取DOM树中CD元素节点的个数
    var cdnodeNum = orderDoc.getElementsByTagName("CD").length;
    //创建一个新元素节点:CD
    var newCdNode = orderDoc.createElement("CD");
    //将id属性节点设置为新建的CD元素节点的属性
    newCdNode.setAttribute("id",(cdnodeNum+1).toString());
    //循环添加CD元素节点的各个子节点
    for(var i=0; i< 6; i++){
        //依据nodeNameArray数组中字符串的先后顺序创建CD的子元素节点
        var cdChildNode = orderDoc.createElement(nodeNameArray[i]);
        //创建文本子节点
        var textNode = orderDoc.createTextNode(document.getElementById("table2").getElementsByTagName("input")[i].value);
        //将文本子节点添加到新建的元素节点中
        cdChildNode.appendChild(textNode);
        //将新建的元素节点添加为之前创建的CD元素节点中,作为其子元素节点。
        newCdNode.appendChild(cdChildNode);
    }
    //将CD元素节点添加的根元素节点中,作为其子元素节点
    root.appendChild(newCdNode);
    //请求服务器保存更新后的XML文档内容,并返回新的XML文档
    saveXmlToPhp();
}
函数:deleteRecord()
function deleteRecord(){
    //获取XML DOM对象中所有CD元素节点
    var cdNodeList = orderDoc.getElementsByTagName("CD");
    //获取根元素节点
    var rootElement = orderDoc.documentElement;
    //获取CD元素节点的个数
    var cdNodeNum = cdNodeList.length;
    //循环找到一个id属性值等于currentRecord的CD元素节点,然后将CD元素节点,从根节点中移除
    for(var i=0;i<cdNodeNum;i++){
        if(cdNodeList[i].getAttribute("id") == currentRecord){
            rootElement.removeChild(cdNodeList[i]);
            break;
        }
    }
    //获得移除后的XML DOM对象中的CD元素节点集
    cdNodeList = orderDoc.getElementsByTagName("CD");
    cdNodeNum =  cdNodeList.length;
    //更新所有CD元素节点的id属性值
    for(var i=0;i<cdNodeNum;i++){
        cdNodeList[i].setAttribute("id",(i+1).toString());
    }
    //请求服务器保存更新后的XML文档,并返回新的XML文档
    saveXmlToPhp();
}
函数:addTrEvent()
/*
为table1的每行添加onclick事件处理方法
 */
function addTrEvent()
{
    var table = document.getElementById("table1");
    for(var i=0;i<table.rows.length;i++){
        table.rows[i].onclick = new Function("trFunc(this)")
    }
}
函数:trFunc(tr)
/*
点击表格记录行时,要处理的事情
 */
function trFunc(tr){
    //记录当前点击的记录行tr元素的属性id的值,以便删除记录使用
    if(!tr){
        return;
    }
    currentRecord = tr.getAttribute("id");
    if(window.cur){
        if(tr.getAttribute("class") == "datarowodd")
            window.cur.style.background = "#efefef";
        else if(tr.getAttribute("class") == "dataroweven")
            window.cur.style.background = "#fff";
    }
    tr.style.background = "#CCC";
    window.cur = tr;
    var childs = tr.childNodes;
    var items = childs.length;
    for(var i=0; i< items; i++){
        if(childs[i].hasChildNodes()){
            //如果有子节点(文本子节点),就将该子节点的值赋值给文本框
            document.getElementById("table2").getElementsByTagName("input")[i].value = childs[i].firstChild.nodeValue;
        }else{
            //如果没有文本子节点,也就是表格单元内容为空时,设置文本框内容为空
            document.getElementById("table2").getElementsByTagName("input")[i].value = "";
        }
    }
}

sendXML.php

<?php
$xmlString = file_get_contents('cd_data.xml');
header('Content-Type: text/xml;charset=utf-8');
echo $xmlString;
?>

saveXML.php

<?php
$besavexml = file_get_contents("php://input");
$XML = simplexml_load_string($besavexml);
$XML->asXML('cd_data.xml');

header('Content-Type: text/xml;charset=utf-8');
echo $besavexml;
?>

css/mystyle.css

.fancytable{border:1px solid #cccccc; width:100%; border-collapse:collapse;}
.fancytable td{border:1px solid #cccccc; color:#555555;text-align:left; line-height:28px;}
.datarowodd{background-color:#ffffff;}
.dataroweven{ background-color:#efefef;}
.headerrow{ background-color:#0066cc;}
.headerrow td{ color:#ffffff; text-align:center;}
.coolborder{
    border:1px solid #0066cc; padding:5px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
}

cd_data.xml

<?xml version="1.0" encoding="utf-8"?>
<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 Tyler</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 Moore</ARTIST>
		<COUNTRY>UK</COUNTRY>
		<COMPANY>Virgin records</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>


代码测试说明:

假设项目所有文件存放在xmldomtest文件夹中,则xmldomtest下的目录结构大致如下:


将xmldomtest这个文件夹拷贝到xampp的安装目录下的htdocs子目录中,启动apache服务器,然后在chrome浏览器地址栏中输入http://127.0.0.1/xmldomtest/index.html即可。

注意事项

所有文件保存到磁盘全部采用utf-8编码方式保存。

测试截图





本人只是略懂皮毛,刚刚初学,东拼西凑出此文章,其根本目的只作为备忘,如能为和我一样的初学者提供一点借鉴和帮助,就略感欣慰了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值