【二十八】xml编程(dom\xpath\simplexml)

1.xml基础概念

作用范围:

  1. 作为程序通讯的标准。
  2. 作为配置文件。
  3. 作为小型数据库。

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>
请输入你要翻译的内容:&nbsp;&nbsp;<input type="text" name="cont">
<input type="hidden" name="type" value="sel">
<input type="submit">
</form>
<form action="res.php" method="post">
<h1>增加单词</h1>
请输入汉语:&nbsp;&nbsp;<input type="text" name="chcont"></br></br>
请输入英文:&nbsp;&nbsp;<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/>";
    }
    
?>
posted @ 2018-01-07 14:21  花花妹子。  阅读(249)  评论(0编辑  收藏  举报