、介绍
XPath(XML Path Language)是一种用于在 XML 文档中定位节点的查询语言。它提供了一种简洁而强大的方式来遍历和选择 XML 文档中的元素和属性
二、语法
表达式 | 描述 | 示例 |
nodename | 选择指定标签名的节点 | html 将选择所有名为html 的节点。 |
* | 选择所有节点 | * 选择文档中的所有节点 |
/nodename | 从根节点开始选择,只能一层一层的往下找 | /html/body/div将选择文档中的所有div 节点 |
//tagname | 选择任意位置的节点 | //div将选择文档中的所有div 节点 |
@ | 选择具有指定属性名和属性值的节点,或者获取属性 | //div[@id="billboard"]//a/@href,[@id="billboard"]获取id=billboard的div,@href获取href属性 |
. | 选取当前节点 | .//div[@id="billboard"] |
.. | 选取当前节点的父节点 | ..//div[@id="billboard"] |
三、谓语
表达式 | 描述 | 示例 |
[condition] | 添加条件来筛选节点 | //div[@id="billboard"]获取id=billboard的div |
position() | 选择具有指定位置的节点 | //div[@id="billboard"]//tr[position()=1]获取第一个tr,等同于 //div[@id="billboard"]//tr[1] |
last() | 选择最后一个节点 | //div[@id="billboard"]//tr[last()] 获取最后一个tr |
四、运算符
表达式 | 描述 | 示例 |
| | 计算两个节点集 | //book | //cd,返回所有拥有 book 和 cd 元素的节点集 |
+ | 加 | 8 + 4 |
- | 减 | 8 - 4 |
* | 乘 | 8 * 4 |
div | 除 | 8 div 4 |
> | 大于 | //div[@id="billboard"]//tr[position()>1]获取位置大于2的tr |
< | 小于 | //div[@id="billboard"]//tr[position()<2]获取位置小于2的tr |
= | 等于 | //div[@id="billboard"]//tr[position()=1]获取第一个tr,等同于 //div[@id="billboard"]//tr[1] |
!= | 非等于 | //div[@id="billboard"]//tr[position()=1]获取位置非等于1的元素 |
>= | 大于等于 | //div[@id="billboard"]//tr[position()>=2]获取位置大于等于2的tr |
<= | 小于等于 | //div[@id="billboard"]//tr[position()<=2]获取位置小于等于2的tr |
and | 与 | //div[@id="billboard"]//tr[@class='test' and position()>2] 获取class为test且位置大于2的tr |
or | 或 | //div[@id="billboard"]//tr[position()=1 or position()=2]获取位置等于1和等于2的tr |
not | 非 | //div[@id="billboard"]//tr[not(position()=1)]获取位置非1的的tr |
五、轴(Axis)
表达式 | 描述 |
ancestor | 选取当前节点的所有先辈(父、祖父等)。 |
ancestor-or-self | 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。 |
attribute | 选取当前节点的所有属性。 |
child | 选取当前节点的所有子元素。 |
descendant | 选取当前节点的所有后代元素(子、孙等)。 |
descendant-or-self | 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
following | 选取文档中当前节点的结束标签之后的所有节点。 |
following-sibling | 选取当前节点之后的所有兄弟节点 |
namespace | 选取当前节点的所有命名空间节点。 |
parent | 选取当前节点的父节点。 |
preceding | 选取文档中当前节点的开始标签之前的所有节点。 |
preceding-sibling | 选取当前节点之前的所有同级节点。 |
self | 选取当前节点。 |
六、常用函数
更多函数请参考:https://www.runoob.com/xpath/xpath-functions.html
表达式 | 描述 | 示例 |
position() | 选择具有指定位置的节点 | //div[@id="billboard"]//tr[position()=1]获取第一个tr,等同于 //div[@id="billboard"]//tr[1] |
last() | 选择最后一个节点 | //div[@id="billboard"]//tr[last()] 获取最后一个tr |
text() | 获取节点的文本内容 | //div[@id="billboard"]//a/text() 获取div[@id="billboard"]下所有a标签中的文本 |
contains(@attr,?'value')???? | 模糊匹配 | //div[@id="billboard"]//a[contains(@href, '35698284')] 选择href中包含35698284的a标签 |
starts-with(@attr,?'value')? | 是否以指定字符开头 | //div[@id="billboard"]//a[starts-with(@href, 'https')] 选择href以https开头的a标签 |
ends-with(@attr,?'value') | 是否以指定字符结尾 | //div[@id="billboard"]//a[ends-with(@href, '35698284')] 选择href以35698284结尾的a标签 |
、什么是节点
回顾概念:
文档:document
元素:页面中所有的标签,元素---element, 标签----元素---对象
节点:页面中所有的内容(标签,属性,文本(文字,换行,空格,回车)),Node
根元素:html标签
节点node | nodeType | nodeName | nodeValue |
元素节点 | 1 | 标签名(大写) | null |
属性节点 | 2 | 属性名 | 属性值 |
文本节点 | 3 | #text | 文本内容 |
CDATA节点 | 4 | #cdata-section | CDATA区域内容 |
实体引用名称节点 | 5 | 引用名称 | null |
实体名称节点 | 6 | 实体名称 | null |
处理指令节点 | 7 | target | entire content cluding the target |
注释节点 | 8 | #comment | 注释内容 |
文档节点 | 9 | #document | null |
文档类型节点 | 10 | doctype的名称 | null |
文档片段节点 | 11 | #document-fragment | null |
DTD声明节点 | 12 | 符号名称 | null |
****节点的属性:(可以使用标签--元素.出来,可以使用属性节点.出来,文本节点.点出来)
nodeType:节点的类型
nodeName:节点的名字
nodeValue:节点的值
二、节点的获取(包含元素节点)
相关html代码
<div id="dv">
<span>这是div中的第一个span标签</span>
<p>这是div中的第二个元素,第一个p标签</p>
<ul id="uu">
<li>乔峰</li>
<li>鹿茸</li>
<li id="three">段誉</li>
<li>卡卡西</li>
<li>雏田</li>
</ul>
</div>
获取父节点(属性):
// 获取某节点的父级节点
node.parentNode
// 获取某节点的父级元素
node.parentElement
获取子节点(属性):
// 获取某节点的子节点
node.childNodes
// 获取某节点的子元素
node.children
属性节点(方法):
// 获取属性节点
node.getAttributeNode("name")
获取其他相关节点(属性)—— 拓展:
// 获取某节点的第一个子节点
node.firstChild;//-----------------------IE8中是第一个子元素
// 获取某节点的第一个子元素
node.firstElementChild;//----------------IE8中不支持
// 获取某节点的最后一个子节点
node.lastChild;//------------------------IE8中是第一个子元素
// 获取某节点的最后一个子元素
node.lastElementChild;//-----------------IE8中不支持
// 获取某节点的前一个兄弟节点
node.previousSibling;
// 获取某节点的前一个兄弟元素
node.previousElementSibling;
// 获取某节点的后一个兄弟节点
node.nextSibling;
// 获取某节点的后一个兄弟元素
node.nextElementSibling;
案例:点击按钮设置div中p标签改变背景颜色(掌握)
html和css代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 300px;
height: 450px;
border: 1px solid red;
}
</style>
</head>
<body>
<input type="button" value="变色" id="btn" />
<div id="dv">
<span>这是span</span>
<p>这是p</p>
<span>这是span</span>
<p>这是p</p>
<span>这是span</span>
<p>这是p</p>
<span>这是span</span>
<a href="http://www.baidu.com">百度</a>
</div>
</body>
</html>
JavaScript代码
<html>
<head>
<title>DOM 教程</title>
</head>
<body>
<h1>DOM 第一课</h1>
<p class="example">Hello world!</p>
<input name="myInput" type="text" size="20" /><br />
<h1 id="myHeader">This is a header</h1>
</body>
</html>
上面的 HTML 中:
<html> 节点没有父节点;它是根节点
<head> 和 <body> 的父节点是 <html> 节点
文本节点 "Hello world!" 的父节点是 <p> 节点
并且:
<html> 节点拥有两个子节点:<head> 和 <body>
<head> 节点拥有一个子节点:<title> 节点
<title> 节点也拥有一个子节点:文本节点 "DOM 教程"
<h1> 和 <p> 节点是同胞节点, 同时也是 <body> 的子节点
并且:
<head> 元素是 <html> 元素的首个子节点
<body> 元素是 <html> 元素的最后一个子节点
<h1> 元素是 <body> 元素的首个子节点
<p> 元素是 <body> 元素的最后一个子节点
访问节点:
var oLi=document.getElementsByTagName("li");
var oLi=document.getElementById("myHeader");
var oLi=document.getElementsByName("myInput"); //通过name属性访问
querySelector访问方式: IE8开始支持, IE8以下不支持
var div=document.querySelector("#myHeader"); //通过id访问
var div=document.querySelector("li"); //通过标签访问
document.querySelector(".example"); //通过class属性访问
获取表单值
document.getElementById(id).value
querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素。
注意: querySelector() 方法仅仅返回匹配指定选择器的第一个元素。
如果你需要返回所有的元素, 请使用 querySelectorAll() 方法替代。
利用父子兄关系查找节点:
使用childNodes属性
对象属性
nodeName 返回当前节点名字
元素节点的 nodeName 是标签名称
属性节点的 nodeName 是属性名称
文本节点的 nodeName 永远是 #text
文档节点的 nodeName 永远是 #document
nodeValue 返回当前节点的值, 仅对文本节点和属性节点
对于文本节点, nodeValue 属性包含文本。
对于属性节点, nodeValue 属性包含属性值。
nodeValue 属性对于文档节点和元素节点是不可用的。
注意:nodeValue与tagName的区别对于空白节点的返回值:nodeValue返回null, tagName返回undefined
对于文本节点的返回值:nodeValue返回文本, tagName返回undefined
nodeType 检测节点类型:
alert(document.nodeType);
元素节点的nodeType值为1; 标签名称
属性节点的nodeType值为2; 属性名称 属性节点不能算是其元素节点的子节点
文本节点的nodeType值为3; #text
注释(Comment) 8: #comment
文档(Document) 9 #document <HTML>
文档类型(DocumentType) 10: <!DOCTYPE HTML PUBLIC"...">
节点 nodeType nodeName nodeValue
元素节点 1 大写的标签名 null
属性节点 2 属性名 属性值
文本节点 3 #text 文本值
tagName 返回标签的名称, 仅对元素节点
parentNode 返回当前节点的父节点, 如果存在的话
childNodes 返回当前节点的子节点集合
firstChild 对标记的子节点集合中第一个节点的引用, 如果存在的话
lastChild 对标记的子节点集合中最后一个节点的引用, 如果存在的话
previousSibling 对同属一个父节点的前一个兄弟节点的引用
nextSibling 对同属一个父节点的下一个兄弟节点的引用
Attributes 返回当前节点(标记)属性的列表 用于XML文件
ownerDocument 返回节点所属的根元素
一些 DOM 对象方法
getElementById() 返回带有指定 ID 的元素。
getElementsByTagName() 返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)。
getElementsByName() 返回包含带有指定类名的所有元素的节点列表。
appendChild() 把新的子节点添加到指定节点。
removeChild() 删除子节点。
replaceChild() 替换子节点。
insertBefore() 在指定的子节点前面插入新的子节点。
createAttribute() 创建属性节点。
createElement() 创建元素节点。
createTextNode() 创建文本节点。
getAttribute() 返回指定的属性值。
setAttribute() 把指定属性设置或修改为指定的值。
删除、替换、插入子节点必须通过父节点的removeChild()方法来完成的
createAttribute() 创建属性节点
var att=document.createAttribute("class");
att.value="democlass";
document.getElementsByTagName("H1")[0].setAttributeNode(att);
以上代码可以简化为
document.getElementsByTagName("H1")[0].class="democlass";
createAttribute()结合setAttributeNode()使用
等同于:
document.getElementsByTagName("H1")[0].setAttributeNode("class", "democlass");
DOM获取所有子节点:
<html>
<head>
<title>childNodes</title>
<script language="javascript">
function myDOMInspector(){
var oUl=document.getElementById("myList"); //获取<ul>标记
var DOMString="";
if(oUl.hasChildNodes()){ //判断是否有子节点
var oCh=oUl.childNodes;
for(var i=0;i<oCh.length;i++) //逐一查找
DOMString +=oCh[i].nodeName + "\n";
}
alert(DOMString);
}
</script>
</head>
<body onload="myDOMInspector()">
<ul id="myList">
<li>糖醋排骨</li>
<li>圆笼粉蒸肉</li>
<li>泡菜鱼</li>
<li>板栗烧鸡</li>
<li>麻婆豆腐</li>
</ul>
</body>
</html>
使用parentNode属性:
<html>
<head>
<title>parentNode</title>
<script language="javascript">
function myDOMInspector(){
var myItem=document.getElementById("myDearFood");
alert(myItem.parentNode.tagName); //返回值为ul
}
</script>
</head>
<body onload="myDOMInspector()">
<ul>
<li>糖醋排骨</li>
<li>圆笼粉蒸肉</li>
<li>泡菜鱼</li>
<li id="myDearFood">板栗烧鸡</li>
<li>麻婆豆腐</li>
</ul>
</body>
</html>
DOM的兄弟关系:
<html>
<head>
<title>Siblings</title>
<script language="javascript">
function myDOMInspector(){
var myItem=document.getElementById("myDearFood");
//访问兄弟节点
var nextListItem=myItem.nextSibling;
var preListItem=myItem.previousSibling;
alert(nextListItem.tagName +" "+ preListItem.tagName);
}
</script>
</head>
<body onload="myDOMInspector()">
<ul>
<li>糖醋排骨</li>
<li>圆笼粉蒸肉</li>
<li>泡菜鱼</li>
<li id="myDearFood">板栗烧鸡</li>
<li>麻婆豆腐</li>
</ul>
</body>
</html>
编写自定义函数解决Firefox等浏览器包含众多的空格作为文本节点问题。
<html>
<head>
<title>Siblings</title>
<script language="javascript">
function nextSib(node){
var tempLast=node.parentNode.lastChild;
//判断是否是最后一个节点,如果是则返回null
if(node==tempLast)
return null;
var tempObj=node.nextSibling;
//逐一搜索后面的兄弟节点,直到发现元素节点为止
while(tempObj.nodeType!=1 && tempObj.nextSibling!=null)
tempObj=tempObj.nextSibling;
//三目运算符,如果是元素节点则返回节点本身,否则返回null
return (tempObj.nodeType==1)?tempObj:null;
}
function prevSib(node){
var tempFirst=node.parentNode.firstChild;
//判断是否是第一个节点,如果是则返回null
if(node==tempFirst)
return null;
var tempObj=node.previousSibling;
//逐一搜索前面的兄弟节点,直到发现元素节点为止
while(tempObj.nodeType!=1 && tempObj.previousSibling!=null)
tempObj=tempObj.previousSibling;
return (tempObj.nodeType==1)?tempObj:null;
}
function myDOMInspector(){
var myItem=document.getElementById("myDearFood");
//获取后一个元素兄弟节点
var nextListItem=nextSib(myItem);
//获取前一个元素兄弟节点
var preListItem=prevSib(myItem);
alert("后一项:" + ((nextListItem!=null)?nextListItem.firstChild.nodeValue:null) + " 前一项:" + ((preListItem!=null)?preListItem.firstChild.nodeValue:null) );
}
</script>
</head>
<body onload="myDOMInspector()">
<ul>
<li>糖醋排骨</li>
<li>圆笼粉蒸肉</li>
<li>泡菜鱼</li>
<li id="myDearFood">板栗烧鸡</li>
<li>麻婆豆腐</li>
</ul>
</body>
</html>
注意:最新版的IE浏览器也包含众多的空格作为文本节点;
设置节点属性:
getAttribute()方法和setAttibute()方法
<html>
<head>
<title>getAttribute()</title>
<script language="javascript">
function myDOMInspector(){
//获取图片
var myImg=document.getElementsByTagName("img")[0];
//获取图片title属性
alert(myImg.getAttribute("title")); //也可以用myImg.title获取属性值
}
</script>
</head>
<body onload="myDOMInspector()">
<img src="01.jpg" title="情人坡" />
</body>
</html>
<html>
<head>
<title>setAttribute()</title>
<script language="javascript">
function changePic(){
//获取图片
var myImg=document.getElementsByTagName("img")[0];
//设置图片src和title属性
myImg.setAttribute("src","02.jpg"); //可以在属性节点不存在时,添加节点的属性值;
myImg.setAttribute("title","紫荆公寓"); //也可以通过myImg.title="紫荆公寓";
}
</script>
</head>
<body>
<img src="01.jpg" title="情人坡" onclick="changePic()" />
</body>
</html>
setAttribute()设置HTML标签的属性
oTable.setAttribute("border", "3"); //为表格边框设置宽度
oTable.setAttribute("border", 3);
oTable.setAttribute("border", "3px"); //经过测试, 此种写法也正确
建议: 具体格式参照HTML属性值的语法格式
setAttibute()设置行内样式
obj.setAttribute("style", "position:absolute;left:200px;top:200px");
注意:具体格式参考CSS样式的语法格式
setAttibute()设置事件属性
obj.setAttribute("onclick", "remove_img()"); //remove_img() 编写自定义函数, 这里不能使用自定义函数
注意:关于文本节点兼容性
元素节点
子节点: childNodes children
首尾子节点: firstChild firstElementChild
lastChild lastElementChild
兄弟节点: nextSibling nextElementSibling
previousSibling previousElementSibling
childNodes firstChild lastChild nextSibling previousSibling属性IE6-IE8版本浏览器不会返回空白节点,
IE9以上版本浏览器会返回文本节点, W3C浏览器(包括火狐浏览器)也会返回文本节点
children firstElementChild lastElementChild nextElementSibling previousElementSibling 只返回元素节点, 不会返回空白节点
注意: DOM操作必须保住DOM节点必须存在, 当然也包括使用css样式display:none隐藏的DOM节点, 否则会导致js语法错误;
*请认真填写需求信息,我们会在24小时内与您取得联系。