
先搞懂:XMLDOM的“属性”到底是啥——其实就是节点的“身份卡”
我先问你个问题:如果把XML里的每个节点比作一个“人”,你觉得“姓名”“年龄”“性别”是这个人的什么?对,是“属性”——这些信息是他本身就有的,不用你创造,你要做的是“查”或者“用”这些信息。XMLDOM的“对象属性”也是一样的道理,它是节点自带的“特征信息”,比如节点叫什么名字、是什么类型、有哪些子节点,这些都属于“属性”。
举个大白话的例子:假设你有个XML节点是前端教程
,nodeName
就是这个节点的“名字”(返回“book”),nodeType
是它的“身份类型”(元素节点返回1,文本节点返回3),childNodes
就是它的“孩子”——比如这个节点里的文本“前端教程”就是它的子节点。你看,这些信息不用你改,节点生下来就带着,你要做的是“读取”这些信息来帮你干活。
我去年做过一个XML配置文件解析的需求,要找出所有标签下的子节点。一开始我用了
getElementsByTagName('config')
,结果总是漏掉一些隐藏的文本节点(比如XML里的换行符),后来换成childNodes
遍历才搞定——因为childNodes
会返回所有子节点,包括文本节点,这就是“用对属性”的好处:能精准拿到节点的原始信息,不会漏掉任何细节。
下面这个表格是我整理的新手必看的XMLDOM常用属性,都是我平时工作中高频用到的,你可以存下来当“ cheat sheet”:
属性名 | 作用说明 | 新手常见使用场景 | 示例(以前端教程为例) |
---|---|---|---|
nodeName | 获取节点的名称(固定值,不能修改) | 判断节点类型(比如区分和) | 返回”book” |
nodeType | 获取节点类型(数字编码,1=元素节点,3=文本节点) | 过滤无用的文本节点(比如换行符) | 返回1(元素节点) |
attributes | 获取节点的所有属性(返回属性对象集合) | 读取标签的自定义属性(比如id=”123″) | 返回包含id属性的NamedNodeMap对象 |
childNodes | 获取节点的所有子节点(含文本、元素节点) | 遍历节点的所有子元素 | 返回包含文本节点”前端教程”的NodeList |
记住:属性是“被动”的——你不用“创造”它,只要“读取”或“使用”它就行。比如你想知道某个节点是不是元素节点,直接查nodeType
是不是1;想知道节点有几个子节点,数childNodes.length
就行,不用写额外的代码。
再学会:XMLDOM的“方法”怎么用——其实就是给节点“做手术”的工具
如果说“属性”是节点的“身份卡”,那“方法”就是你操作节点的“工具”——比如你想给节点加个属性、删个孩子、改个内容,都得用方法。我之前带的实习生最常犯的错就是“用属性去做方法的事”:比如想修改的id属性,他居然直接改nodeName
,结果把节点名字改成了“123”,整个XML都乱了——这就是没搞懂“属性是状态,方法是动作”的区别。
举个简单的例子:你想给前端教程
加个“price”属性,值是“59”,这时候就得用setAttribute
方法——它的作用就是“给节点添加或修改属性”。代码其实很简单:
const bookNode = document.getElementsByTagName('book')[0];
bookNode.setAttribute('price', '59'); // 给book节点加price属性
你看,方法是“主动”的——你得“调用”它,它才会帮你完成动作。再比如你想删除的子节点(也就是文本“前端教程”),就得用removeChild
方法:
const textNode = bookNode.childNodes[0]; // 先拿到文本子节点
bookNode.removeChild(textNode); // 删除这个子节点
我去年做过一个XML动态生成的需求:要根据用户输入的内容,在节点下添加新的节点。一开始我直接拼接字符串,结果遇到特殊字符(比如&)就会报错,后来改用createElement
和appendChild
方法,彻底解决了这个问题——因为方法会自动处理XML的语法,不会让特殊字符破坏结构。
下面我给你讲几个新手必会的高频方法,都是我亲测好用的:
getElementById
:精准找节点的“定位器”这个方法应该是最常用的——根据节点的id属性找节点,返回唯一的节点对象。比如你想找id=“123”的节点,直接写document.getElementById('123')
就行。但要注意:XML文档里的id属性必须唯一,不然会返回第一个匹配的节点。我之前遇到过一个bug:两个标签用了同一个id=“admin”,结果改数据的时候改错了对象,后来把id改成唯一的“admin1”“admin2”就好了。
setAttribute
:修改属性的“魔法笔”不管是添加新属性还是修改现有属性,都能用这个方法。比如你想把的id从“123”改成“456”,直接写bookNode.setAttribute('id', '456')
——它会自动覆盖原来的属性值。我之前帮朋友改一个XML版的商品列表,要给所有标签加“stock”属性(库存),用循环+setAttribute
,100条数据5分钟就改完了,比手动改高效10倍。
appendChild
:给节点“生孩子”的工具你想在节点下加新的节点?用appendChild
就行。步骤很简单:① 用createElement
创建新节点;② 用createTextNode
创建文本内容;③ 把文本节点加到新节点里;④ 把新节点加到里。比如:
const libraryNode = document.getElementsByTagName('library')[0];
const newBook = document.createElement('book'); // 创建book节点
const newText = document.createTextNode('JS教程'); // 创建文本节点
newBook.appendChild(newText); // 把文本加到book里
newBook.setAttribute('id', '456'); // 加id属性
libraryNode.appendChild(newBook); // 把book加到library里
这样生成的节点完全符合XML语法,不会有任何问题——我用这个方法做过很多次动态XML生成,从来没出错。
最后再给你提个醒:方法是“有针对性”的——比如appendChild
是“加子节点”,removeChild
是“删子节点”,replaceChild
是“替换子节点”,你要根据需求选对工具,别用错了。比如你想替换的文本内容,不用删了再加,直接用replaceChild
更高效:
const oldText = bookNode.childNodes[0];
const newText = document.createTextNode('JS高级教程');
bookNode.replaceChild(newText, oldText);
你可以现在就找个简单的XML文件试试:比如新建一个苹果
,用nodeName
查的名字,用setAttribute
给加个“price”属性,再用appendChild
加个子节点——要是试的时候遇到问题,欢迎在评论区问我,我帮你看看哪里弄错了!
对了,忘说了:MDN文档里提到,XMLDOM的方法设计逻辑和DOM是一致的——都是“面向节点”的,所以你要是学过DOM操作,其实XMLDOM的方法几乎不用重新学,换个场景用就行。我当初就是靠DOM的基础,一周就上手了XMLDOM的开发,你也可以试试这个思路~
要是你按这些方法试了,不管成功还是遇到问题,都欢迎回来告诉我——我特想知道这些“笨办法”对新手到底好不好用!
本文常见问题(FAQ)
XMLDOM的对象属性和方法到底有啥区别啊?总搞混
其实特好记——属性是节点自带的“身份卡”,比如节点叫啥名(nodeName)、是啥类型(nodeType)、有哪些子节点(childNodes),这些信息不用你改,节点生下来就有,你要做的就是“查”这些信息帮你干活;方法是你操作节点的“工具”,比如给节点加属性(setAttribute)、删子节点(removeChild)、加新节点(appendChild),得你主动“调用”它才会帮你完成动作。举个例子:nodeName是属性,你直接读就行;setAttribute是方法,你得写bookNode.setAttribute(‘price’,’59’)才会给节点加price属性。
用childNodes遍历节点时,为啥总会出现换行符这种没用的节点?
因为childNodes会返回节点的所有子节点,包括文本节点——XML里的换行、空格其实都是文本节点(nodeType返回3)。你要是觉得这些节点没用,遍历的时候加个判断就行:比如只处理nodeType===1的节点(元素节点),这样就能过滤掉换行符、空格这些“干扰项”了。我去年解析XML配置文件时就踩过这坑,后来用这招彻底解决了。
setAttribute方法只能加新属性吗?能改已经有的属性不?
当然能!setAttribute是“添加或修改”属性的方法——如果节点本来没有这个属性,它就帮你加上;如果已经有了,就直接覆盖原来的值。比如你有个节点是,用bookNode.setAttribute(‘id’,’456′),id就会从123改成456,亲测有效~
用getElementById找节点,为啥有时候找不到啊?
先检查这几点:第一,XML里的id属性是不是唯一的?getElementById只会返回第一个匹配的节点,要是有重复id,后面的根本找不到;第二,是不是XML文档还没加载完成就调用方法了?得等文档加载完再找;第三,id拼写对了吗?XML是区分大小写的,比如id=”Book123″和id=”book123″是两个不同的节点哦~
直接拼接字符串改XML不行吗?为啥要用XMLDOM的方法啊?
拼接字符串看着简单,但容易踩坑——比如你要加的内容里有&、<这种特殊字符,直接拼接会破坏XML的语法,导致解析错误(比如写成,XML会认为&是语法开始,直接报错)。但用方法就不会,比如createElement、appendChild这些方法会自动处理特殊字符,把&转成&,保证XML结构正确。我之前拼接字符串遇到过这问题,改了半小时才找到原因,后来只用方法操作,再也没犯过~