XML学习(语法+css+DOM)详解

因为自己选修了XML这门课,所以想现在就开始学习。
文中用到的xml:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <book category="cooking">
        <title lang="en">Everyday Italian</title>
        <author>Giada De Laurentiis</author>
        <year>2005</year>
        <price>30.00</price>
    </book>
    <book category="children">
        <title lang="en">Harry Potter</title>
        <author>J K. Rowling</author>
        <year>2005</year>
        <price>29.99</price>
    </book>
    <book category="web">
        <title lang="en">XQuery Kick Start</title>
        <author>James McGovern</author>
        <author>Per Bothner</author>
        <author>Kurt Cagle</author>
        <author>James Linn</author>
        <author>Vaidyanathan Nagarajan</author>
        <year>2003</year>
        <price>49.99</price>
    </book>
    <book category="web" cover="paperback">
        <title lang="en">Learning XML</title>
        <author>Erik T. Ray</author>
        <year>2003</year>
        <price>39.95</price>
    </book>
</bookstore>

xml与html

xmlhtml其实并没有太大关系,html经常被用来显示数据,让用户直观的看到效果,而xml被用来传输和储存数据,xml的写法是类似于html的,但xml中的标签都是自定义标签
xml的文档结构也是类似于html的DOM树结构。

语法

基本结构:

在文档开头需要首先声明是xml文档:

<?xml version="1.0" encoding="UTF-8"?>

xml中必须要有根元素,类似于:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <child>
        <subchild></subchild>
    </child>
    <secondchild></secondchild>
</root>

root就是根元素,根据划分有一层一层的子元素。

xml中所有标签都必须要有闭合标签。

xml中空格不会被删减。

实体引用:

xml实体引用:

&gt;>
&lt;<
&amp;&
&apos;
&quot;"

在 XML 中,只有字符 "<""&" 确实是非法的,必须用实体引用代替。

css

xml文档中的元素也可以用css来决定样式,我们需要引用css文件:

<?xml-stylesheet href="file.css" type="text/css"?>

DOM

xmlDOM可以根据htmlDOM来学习,基本功能都是一样的。事先了解html的DOM会更容易理解。

如何获取xml

    if (window.XMLHttpRequest)
    {
        // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
        xhttp=new XMLHttpRequest();
    }
    else
    {
         // IE6, IE5 浏览器执行代码
        xhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xhttp.open("GET","test.xml",false);//创建一个新的请求,带有请求方法、URL、验证信息
    xhttp.send();//将请求发送至服务器
    xmlDoc=xhttp.responseXML;//定义变量接收返回的信息

更多的可以去看看我之前写的AJAX部分:AJAX学习
这样我们就获得了xml结构的数据。

属性和方法

属性:

  • x.nodeName : x 的名称
  • x.nodeValue :x 的值
  • x.nodeType:x的节点类型
  • x.parentNode : x 的父节点
  • x.childNodes :x 的子节点
  • x.attributes : x 的属性节点
  • x.firstChild:x的第一个子节点
  • x.lastChild:x的最后一个子节点
  • x.nextSibling:x的下一个兄弟节点
  • x.previousSibling:x的上一个兄弟节点

方法:

  • x.appendChild(node) : 向 x 插入子节点
  • x.removeChild(node) :从 x 删除子节点
  • x.getAttributeNode():返回x节点的某属性节点
  • x.getAttribute() :返回x节点的某属性值

节点

节点类型

  • 文档节点:整个文档就是一个文档节点
  • 元素节点:xml元素
  • 文本节点:包含在xml元素中的文本
  • 属性节点:xml元素属性
  • 注释节点:注释

节点属性

节点有三个重要的属性:

  • nodeName:节点名称
  • nodeValue:节点的值
  • nodeType:节点类型

nodeName:

元素节点的 nodeName 与标签名相同
属性节点的 nodeName 是属性的名称
文本节点的 nodeName 永远是 #text
文档节点的 nodeName 永远是 #document

document.write(xmlDoc.nodeName+'</br>');//文档节点的nodeName
document.write(xmlDoc.documentElement.nodeName+'</br>');//根节点的nodeName
document.write(xmlDoc.getElementsByTagName("title")[0].nodeName+'</br>');//第一个title元素节点的nodeName
document.write(xmlDoc.getElementsByTagName("title")[0].attributes[0].nodeName+'</br>');//第一个title元素节点的第一个属性节点的nodeName
document.write(xmlDoc.getElementsByTagName("title")[0].firstChild.nodeName);

在这里插入图片描述
nodeValue

元素节点的 nodeValueundefined
文本节点的 nodeValue文本本身
属性节点的 nodeValue属性的值

document.write(xmlDoc.nodeName+'(value:'+xmlDoc.nodeValue+')'+'</br>');//文档节点的nodeValue
document.write(xmlDoc.documentElement.nodeName+'(value:'+xmlDoc.documentElement.nodeValue+')'+'</br>');//根节点的nodeValue
var x=xmlDoc.documentElement.childNodes[1].childNodes[1];//第一个title元素节点
document.write(x.nodeName+'(value:'+x.nodeValue+')'+'</br>');//第一个title元素节点的nodeValue
document.write(x.attributes[0].nodeName+'(value:'+x.attributes[0].nodeValue+')'+'</br>');//第一个title元素节点的第一个属性节点的nodeValue
document.write(x.firstChild.nodeName+'(value:'+x.firstChild.nodeValue+')');//第一个title元素节点的文本节点的nodeValue

在这里插入图片描述
到这里为什么我的childNodes是选取的[1]而不是[0]?
可以看我的另一篇:XML获取节点时多出来#text

nodeType:

节点类型nodeType
元素1
属性2
文本3
注释8
文档9

对节点的操作

改变值

  • 改变文本节点的值:用文本节点的nodeValue属性
  • 改变属性节点的值:用setAttribute()方法设置属性值或用属性节点的nodeValue属性
    //改变元素的值其实就是改变元素中文本节点的值
    x=xmlDoc.getElementsByTagName("title")[0];//获取第一个title
    console.log(x.childNodes[0].nodeValue);
    x.childNodes[0].nodeValue='hello world';
    console.log(x.childNodes[0].nodeValue);

    //改变属性节点的值
    console.log(x.getAttribute('lang'));//输出title节点属性为lang的值
    x.setAttribute('lang','fun');
    console.log(x.getAttribute('lang'));

    //用nodeValue重写上面方法
    //getAttribute()/setAttribute()=getAttributeNode().nodeValue
    console.log(x.getAttribute('lang'));//输出title节点属性为lang的值
    console.log(x.getAttributeNode('lang').nodeValue);
    x.getAttributeNode('lang').nodeValue='fun2';
    console.log(x.getAttribute('lang'));

在这里插入图片描述

删除节点

  • 删除节点removeChild():所有的节点都可以删除
  • 清空文本节点nodeValue=""
  • 根据名称删除属性节点removeAttribute(name)
  • 根据对象删除属性节点removeAttributeNode(node)
    console.log(xmlDoc.documentElement.childNodes);
    //删除元素节点
    x=xmlDoc.getElementsByTagName("book");//获取book节点列表,长度为4
    xmlDoc.documentElement.removeChild(x[0]);//在根节点(bookstore)中删除第一个book节点,长度为3
    console.log(xmlDoc.documentElement.childNodes);

    //删除自身节点
    //如果不知道book节点的父节点就是根节点的情况下,可以使用parentNode
    x[0].parentNode.removeChild(x[0]);//在x[0]的父节点中删除x[0]节点,长度为2
    console.log(x[0].parentNode.childNodes);

    //removeChild可以移除所有的节点,包括文本节点
    //文本节点也可以用nodeValue属性
    console.log(x[0].childNodes[1].firstChild.nodeValue);
    x[0].childNodes[1].firstChild.nodeValue="";//清空book[0]下的title下的文本节点
    console.log(x[0].childNodes[1].firstChild.nodeValue);

    //删除属性节点
    console.log(x[0].getAttribute('category'));
    x[0].removeAttribute('category');
    console.log(x[0].attributes);
        //利用 removeAttributeNode(x)
    console.log(x[1].getAttributeNode('cover').nodeValue);
    x[1].removeAttributeNode(x[1].attributes[1]);
    console.log(x[1].attributes);

替换节点

  • replaceChild(newNode,oldNode):替换元素节点
  • replaceData(offset,length,string):替换文本节点的数据(nodeValue也可以)
    x=xmlDoc.documentElement;//根节点
    console.log(x.childNodes[1]);

    newNode=xmlDoc.createElement("book");
    newTitle=xmlDoc.createElement("title");
    newText=xmlDoc.createTextNode("A Notebook");

    newTitle.appendChild(newText);
    newNode.appendChild(newTitle);

    x.replaceChild(newNode,xmlDoc.getElementsByTagName("book")[0]);//用newNode替换第一个book节点

    console.log(x.childNodes[1]);

    xmlDoc.getElementsByTagName("title")[1].childNodes[0].replaceData(10,11,"Two");
    //第二个title节点的文本节点的第10个字符替换为Two
    console.log(x.childNodes[3]);

    xmlDoc.getElementsByTagName("title")[2].childNodes[0].nodeValue="hello world";
    console.log(x.childNodes[5]);

在这里插入图片描述

创建节点

  • createElement():创建新的元素节点
  • createAttribute():创建新的属性节点
  • setAttribute():在属性不存在的情况下,创建新的属性节点并赋值
  • createTextNode():创建新的文本节点
    x=xmlDoc.documentElement;//根节点
    console.log(x.childNodes);

    newNode=xmlDoc.createElement("book");//创建一个新的book节点
    newTitle=xmlDoc.createElement("title");//创建一个新的title节点
    newText=xmlDoc.createTextNode("hello world");//创建新的文本节点,内容是hello world
    newAttr=xmlDoc.createAttribute("lang");//创建新的属性节点
    newAttr.nodeValue="en";//给lang赋值为en
    newTitle.setAttribute("name","lucy");//不存在该属性,创建并赋值

    newTitle.setAttributeNode(newAttr);//将属性节点添加到title节点中
    newTitle.appendChild(newText);//将文本节点添加到title节点中
    newNode.appendChild(newTitle);//将title节点添加到book节点中

    x.appendChild(newNode);//将book节点添加到根节点中

    console.log(x.childNodes[9]);

在这里插入图片描述

添加节点

注意:添加属性节点不能使用appendChild(),可以用setAttribute()setAttributeNode()

  • appendChild():在已有节点的后面追加节点
  • insertBefore(i,j):在j节点之前插入i节点
  • insertData(offset,string):在已有文本节点的offset位置后插入string
    newauthor=xmlDoc.createElement("author");//创建作者节点
    newText2=xmlDoc.createTextNode("me");//创建文本节点
    newauthor.appendChild(newText2);//将文本节点添加到author节点中

    newNode.appendChild(newauthor);//在book节点的最后面追加节点author,插入到title节点后
    
    newyear=xmlDoc.createElement("year");//创建year节点
    newText3=xmlDoc.createTextNode("2020");//创建文本节点
    newyear.appendChild(newText3);//将文本节点追加到year节点

    newNode.insertBefore(newyear,newTitle);//将year节点添加到title节点之前
    newText3.insertData(newText3.nodeValue.length,"我是后来加上的");

在这里插入图片描述

克隆节点

当我们想在bookstore中添加新的book节点,如果我们想添加多个,而又因为一个节点只能插入到一个节点中,比如:

    newauthor=xmlDoc.createElement("author");//创建作者节点
    // newText2=xmlDoc.createTextNode("me");//创建文本节点
    newauthor.appendChild(newText);//将文本节点添加到author节点中

    newNode.appendChild(newauthor);//在book节点的最后面追加节点author,插入到title节点后
    
    newyear=xmlDoc.createElement("year");//创建year节点
    // newText3=xmlDoc.createTextNode("2020");//创建文本节点
    newyear.appendChild(newText);//将文本节点追加到year节点

    newNode.insertBefore(newyear,newTitle);//将year节点添加到title节点之前
    newText.insertData(newText.nodeValue.length,"我是后来加上的");

跟上面程序对比,我们想要达到将newText这个节点插入到所有节点当中,但结果却不是这样:
在这里插入图片描述
所以代表一个节点的这个变量只能插入到一个节点当中。

我们就可以使用克隆cloneNode(true/false)

  • true:克隆当前节点的属性及子节点
  • false:不包括
    cloneNode=newNode.cloneNode(true);//克隆newNode节点以及其所有的属性和子节点
    x.appendChild(cloneNode);//将克隆节点插入到根节点

    console.log(x.childNodes[10]);

在这里插入图片描述
在这里插入图片描述

节点列表

  • 属性length-节点列表的长度
  • 方法item(index)-返回节点列表中指定索引号的节点。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值