【二十八】xml编程(dom\xpath\simplexml)
1.xml基础概念
作用范围:
- 作为程序通讯的标准。
- 作为配置文件。
- 作为小型数据库。
xml语法:
<根标签> <标签 元素="元素值" ...></标签> ... <标签 元素="元素值" ...></标签> </根标签>
xm的注意点
- 必须有关闭标签
- 对大小写敏感
- 必须要正确的嵌套
- 必须有根元素
- 属性值必须加引号
2.CDATA节
概念:CDATA是不通过解析器进行解析的文本,文本中的标签不被看作标记。
注意:所有的资源都是二进制。是不能直接存在xml的,需要转义。或者使用CDATA
语法:<![CDATA[" 值 "]]>
<?xml version="1.0" encoding="UTF-8"?> <!-- version="1.0" 声明用的xml版本是1.0 encoding="UTF-8"声明用xml传输数据的时候的字符编码,假如文档里面有中文,编码方式不是UTF-8,传输过去再解码的话中文就会是乱码 --> <!--这是注释--> <班级> <stu stuNo="fdsafdsfdsf;" stuNo2="t-33"> <name>花花</name> <age>20</age> <介绍><![CDATA[eqre!@#¥%……&%¥#¥]]></介绍> </stu> </班级>
面试题:请问如果使用xml来保存及传递图片?
答:使用程序先读到内存,然后保存到xml的<![CDATA[" 文件内容 "]]>(任何资源都是需要先读取到内存,)
3.处理指令PI(processing instruction)
classes1.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- version="1.0" 声明用的xml版本是1.0 encoding="UTF-8"声明用xml传输数据的时候的字符编码,假如文档里面有中文,编码方式不是UTF-8,传输过去再解码的话中文就会是乱码 --> <!--这是注释--> <!-- 使用PI指令来引入css修饰 --> <!-- 引入外部css --> <?xml-stylesheet type="text/css" href="xmlcss.css"?> <班级> <stu stuNo="fdsafdsfdsf;" stuNo2="t-33"> <name>花花</name> <age>20</age> <介绍><![CDATA[eqre!@#¥%……&%¥#¥]]></介绍> </stu> </班级>
xmlcss.css
name{
font-size: 100px;
font-weight: bold;
color: red;
}
age{
font-size: 50px;
font-weight: bold;
color: blue;
}
介绍{
font-size: 20px;
font-weight: bold;
color: yellow;
}
界面显示:
4.文件约束DTD(document type definition)
常用约束:DTD、Schema
作用:dtd主要用处是约束html、xml、xhtml文件等。默认情况下浏览器不检测文件是否符合dtd,需要自己编写代码测试。
内部dtd:
<!DOCTYPE 根元素名 [
<!ELEMENT 元素名 (元素类型定义)>
]>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE 班级 [ <!ELEMENT 班级 (学生+)> <!ELEMENT 学生 (名字,年龄,介绍)> <!ELEMENT 名字 (#PCDATA)> <!ELEMENT 年龄 (#PCDATA)> <!ELEMENT 介绍 (#PCDATA)>]> <班级> <学生> <名字>花花</名字> <年龄>20</年龄> <介绍>这是我的介绍</介绍> <面积>555</面积> </学生> </班级>
外部dtd:
<!DOCTYPE 根元素名 SYSTEM "外部DTD文件的URI">(SYSTEM表示DTD文件是私有的。引号不能少)
<!-- 私有引用 --> <!DOCTYPE 班级 SYSTEM "class2.dtd"> <!-- 公开引用 --> <!DOCTYPE 根元素 PUBLIC "dtd的名称" "dtd文件的url">
dtd基本语法:
<!ELEMENT 元素名称 (子元素名称)>
+:1~多
?:0~1
*:0~多
DTD验证:写一个脚本去验证xml是否符合dtd约束
classes1.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- 引入dtd --> <!DOCTYPE 班级 SYSTEM "class2.dtd"> <班级> <学生> <名字>花花</名字> <年龄>20</年龄> <介绍>这是我的介绍</介绍> <面积>555</面积> </学生> <学生> <名字>qq</名字> <年龄>27</年龄> <介绍>好好学习</介绍> </学生> </班级>
class2.dtd
<!ELEMENT 班级 (学生+)> <!ELEMENT 学生 (名字,年龄,介绍)> <!ELEMENT 名字 (#PCDATA)> <!ELEMENT 年龄 (#PCDATA)> <!ELEMENT 介绍 (#PCDATA)>
test.html
<!DOCTYPE html> <html> <head> <title>测试dtd</title> <meta charset="utf-8" content="text/html;chatset=utf-8" /> <script language="javascript" > // // 创建xml文档解析器对象 var xmlDoc = new ActiveXObject("Microsoft.XMLDOM") xmlDoc.async="false" // 开启xml校验 xmlDoc.validateOnParse="true" // 装载xml文档,即指定校验哪个XML文件 xmlDoc.load("classes1.xml") document.write("<br>Error Code: ") document.write(xmlDoc.parseError.errorCode) document.write("<br>Error Reason: ") document.write(xmlDoc.parseError.reason) document.write("<br>Error Line: ") document.write(xmlDoc.parseError.line) </script> </head> </html>
结果:
dtd属性
语法:<!ATTLIST 元素名称 属性名称 属性类型 默认值>
5.XML编程
php dom :文档对象模型(document object moudle)
1.查看xml中内容
classes1.php
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!-- 引入dtd --> 3 <!DOCTYPE 班级 SYSTEM "class2.dtd"> 4 <班级> 5 <学生 > 6 <名字>花花</名字> 7 <年龄>20</年龄> 8 <介绍>这是我的介绍</介绍> 9 </学生> 10 <学生> 11 <名字>qq</名字> 12 <年龄>27</年龄> 13 <介绍>好好学习</介绍> 14 </学生> 15 <班长>我</班长> 16 </班级>
phpdom.php
<?php // 1.创建dom解析器 $xml=new DOMDocument(); //2.加载xml文件 $xml->load("classes1.xml"); // 3.获取所有学生 $stus=$xml->getElementsByTagName("学生"); for ($i=0; $i <$stus->length ; $i++) { $stu=$stus->item($i); echo getnodeval($stu,"名字")."----".getnodeval($stu,"年龄").getnodeval($stu,"介绍")."<br/>"; } function getnodeval($mynode,$tagname){ return $mynode->getElementsByTagName($tagname)->item(0)->nodeValue; } ?>
2.使用php增加xml中的内容
<?php // 1.创建dom解析器 $xml=new DOMDocument(); //2.加载xml文件 $xml->load("classes1.xml"); // 3.添加一个学生信息 // 3.1 得到根节点 $root=$xml->getElementsByTagName("班级")->item(0); // 3.2创建学生节点 $stu_node=$xml->createElement("学生"); // 3.2在创建名字节点 $stu_node_name=$xml->createElement("名字"); $stu_node_name->nodeValue="菜菜"; // 把名字节点挂载到“学生”节点下 $stu_node->appendChild($stu_node_name); // 3.3 创建年龄节点 $stu_node_age=$xml->createElement("年龄"); $stu_node_age->nodeValue="18"; $stu_node->appendChild($stu_node_age); // 3.4 创建介绍节点 $stu_node_inrto=$xml->createElement("介绍"); $stu_node_inrto->nodeValue="cmf"; $stu_node->appendChild($stu_node_inrto); // 4.把学生节点挂在到根节点 $root->appendChild($stu_node); //重新保存xml $xml->save("classes1.xml"); ?>
3.删除xml中的内容(注意:必须要重新保存。不然修改的内容在内存中改变了,但文件中的内容没有改变)
<?php // 1.创建dom解析器 $xml=new DOMDocument(); //2.加载xml文件 $xml->load("classes1.xml"); // 3.添加一个学生信息 // 3.1 得到根节点 $root=$xml->getElementsByTagName("班级")->item(0); //3.2找到要删除的学生,比如第二个学生 $stus=$xml->getElementsByTagName("学生"); $stu=$stus->item(1); // 4.删除第二个学生,将第二个学生的节点从根节点移除 // 方法一********************* // $root->removeChild($stu); // 方法二(不依赖根节点,直接通过父节点去删除)********************* $stu->parentNode->removeChild($stu); $xml->save("classes1.xml"); ?>
4.更新xml中的内容
<?php // 1.创建dom解析器 $xml=new DOMDocument(); //2.加载xml文件 $xml->load("classes1.xml"); //更新步骤 //1.找到要修改的节点 //2.重新赋值 $stus=$xml->getElementsByTagName("学生"); $stu1=$stus->item(0); $stu1_age=$stu1->getElementsByTagName("年龄")->item(0); // 给这个学生的年龄+10 $stu1_age->nodeValue+=10; //保存文件 $xml->save("classes1.xml"); ?>
翻译词条例题:
index.php(主界面)
<!DOCTYPE html> <html> <head> <title>翻译</title> </head> <body> <img src="ciba.png" width="200" height="100"> <form action="res.php" method="post"> <h1>查询单词</h1> 请输入你要翻译的内容: <input type="text" name="cont"> <input type="hidden" name="type" value="sel"> <input type="submit"> </form> <form action="res.php" method="post"> <h1>增加单词</h1> 请输入汉语: <input type="text" name="chcont"></br></br> 请输入英文: <input type="text" name="encont"></br></br> <input type="hidden" name="type" value="add"> <input type="submit"> </form> </body> </html>
caba.xml(xml信息,存取数据)
<?xml version="1.0" encoding="UTF-8"?> <words> <word> <en>buy</en> <ch>买</ch> </word> <word> <en>hello</en> <ch>你好</ch> </word> <word> <en>go</en> <ch>走</ch> </word> </words>
res.php(结果页面)
1 <?php 2 //接收类型 3 $type=$_POST['type']; 4 echo $type; 5 //创建dom解析器 6 $xml=new DOMDocument(); 7 //加载xml文件 8 $xml->load("ciba.xml"); 9 // 判断类型 10 if ($type=="sel") { 11 $enwords=$_POST['cont']; 12 // 获取word节点 13 $words=$xml->getElementsByTagName("words")->item(0)->getElementsByTagName("word"); 14 $flag=false; 15 for ($i=0; $i <$words->length ; $i++) { 16 $word=$words->item($i); 17 $xmlword=getvalue($word,"en"); 18 if ($enwords==$xmlword) { 19 echo $enwords."对应的汉语翻译为".getvalue($word,"ch")."</br>"; 20 $flag=true; 21 } 22 } 23 if (!$flag) { 24 echo "没有对应的词条"."</br>"; 25 } 26 }elseif ($type=="add") { 27 $enword=$_POST["encont"]; 28 $chword=$_POST["chcont"]; 29 // 找到根节点,创建word节点,将word节点挂在到根节点上 30 $words=$xml->getElementsByTagName("words")->item(0); 31 $word_node=$xml->createElement("word"); 32 $words->appendChild($word_node); 33 // 创建en节点,为en节点赋值。将en节点挂在到word节点上 34 $en_node=$xml->createElement("en"); 35 $en_node->nodeValue=$enword; 36 $word_node->appendChild($en_node); 37 // 创建ch节点,为ch节点赋值。将ch节点挂在到word节点上 38 $en_node=$xml->createElement("ch"); 39 $en_node->nodeValue=$chword; 40 $word_node->appendChild($en_node); 41 // 将修改的内容保存到xml中 42 $xml->save("ciba.xml"); 43 echo "添加成功"; 44 } 45 function getvalue($mynode,$word){ 46 return $mynode->getElementsByTagName($word)->item(0)->nodeValue; 47 } 48 echo "<br/><br/><a href='index.php'>返回主界面</a>"; 49 ?>
界面展示:
6.xpath(是一种标识节点位置的语言,用来描述xml元素的位置)
xpath的设计核心思想:可以通过xpath迅速简捷的定位你希望查找的节点(不能增删改)
test.xml
<?xml version="1.0" encoding="UTF-8"?> <aaa> <bbb/> <ccc/> <bbb/> <ddd> <bbb/> </ddd> <ccc/> </aaa>
test.php
<?php // 1.创建dom解析器 $xmldoc=new DOMDocument(); //2.加载xml文件 $xmldoc->load("test.xml"); $domxpath=new DOMXPath($xmldoc); $nodelist=$domxpath->query("/aaa/ccc"); for ($i=0; $i <$nodelist->length ; $i++) { echo $nodelist->item($i)->tagName."<br/>"; } ?>
7.simpleXML
核心思想:以面向对象的方式来操作xml
stu.xml
<?xml version="1.0" encoding="UTF-8"?> <班级> <学生 stu="001"> <名字>花花</名字> <年龄>40</年龄> <介绍>这是我的介绍</介绍> </学生> <学生 stu="002"> <名字>菜菜</名字> <年龄>18</年龄> <介绍>cmf</介绍> </学生> </班级>
test.xml
<?php // 装载一个xml文件 $lib=simplexml_load_file("stu.xml"); var_dump($lib); //取出介绍 $insto=$lib->学生; // echo $insto=$insto[0]->介绍."<br/>"; for ($i=0; $i <count($insto) ; $i++) { // $in=$insto[$i]; // echo $in->介绍; // 取出属性的值 echo $insto[$i]['stu']; // 取出所有的元素 foreach ($insto[$i] as $key => $value) { echo "$key-----$value<br/>"; } } // simplexml也可以和xpath结合.取出介绍 foreach ($lib->xpath("//介绍") as $key => $value) { echo $value."<br/>"; } ?>