XML DOM – Attr 对象

XML DOM – Attr 对象(属性节点)

Attr(属性节点)是 XML DOM 中代表元素属性的专用节点类型。尽管它在现代 JavaScript 中不推荐直接操作(推荐用 getAttribute / setAttribute),但理解它的存在和特性非常重要,尤其是在遍历 attributes 集合、处理命名空间、序列化、调试时。

1. 基本信息

项目值/说明
nodeType2(Node.ATTRIBUTE_NODE
nodeName属性名(带前缀时包含前缀,如 xlink:href
nodeValue属性值(字符串)
textContent等同于 nodeValue
value等同于 nodeValue(Attr 独有,最常用)
name等同于 nodeName
ownerElement所属的 Element 对象(非常有用)
specified布尔值,true 表示显式设置(历史遗留,几乎恒为 true)

2. 命名空间相关属性(关键!)

属性说明示例
localName不带前缀的本地名称href
prefix命名空间前缀(可能为 null)xlink
namespaceURI命名空间 URI(可能为 null)http://www.w3.org/1999/xlink
ownerDocument所属文档

示例:

<book xmlns:xlink="http://www.w3.org/1999/xlink"
      id="b1"
      xlink:href="details.xml">
</book>
const book = doc.querySelector("book");
const attr = book.attributes.getNamedItem("xlink:href"); // 或 book.getAttributeNode("xlink:href")

console.log(attr.name);          // "xlink:href"
console.log(attr.localName);     // "href"
console.log(attr.prefix);        // "xlink"
console.log(attr.namespaceURI);  // "http://www.w3.org/1999/xlink"
console.log(attr.value);         // "details.xml"
console.log(attr.ownerElement === book); // true

3. 如何获取 Attr 对象(4 种方式)

const el = doc.documentElement;

// 1. 最常用:通过 attributes NamedNodeMap
const attr1 = el.attributes["id"];           // 推荐
const attr2 = el.attributes.getNamedItem("id");

// 2. 传统方法(已不推荐)
const attr3 = el.getAttributeNode("id");     // 即将废弃

// 3. 带命名空间
const attr4 = el.attributes.getNamedItemNS(
    "http://www.w3.org/2000/xmlns/", "xlink"
);

4. 创建和设置 Attr 对象(不推荐,但可行)

// 方法1:createAttribute(不带命名空间)
const attr = doc.createAttribute("data-custom");
attr.value = "123";
el.setAttributeNode(attr);  // 添加到元素

// 方法2:createAttributeNS(带命名空间,推荐用于 xmlns、xlink 等)
const xlink = doc.createAttributeNS(
    "http://www.w3.org/2000/xmlns/",
    "xmlns:xlink"
);
xlink.value = "http://www.w3.org/1999/xlink";
el.setAttributeNodeNS(xlink);

强烈建议:直接使用 setAttribute() / setAttributeNS(),不要手动创建 Attr。

5. 实际用途场景(Attr 对象真正有用的地方)

场景为什么需要 Attr 对象而不是 getAttribute?
遍历所有属性(包括命名空间声明)element.attributes 返回所有 Attr
精确控制属性顺序(部分 XML 工具在意顺序)NamedNodeMap 可以 insertBefore
复制属性到另一个元素newEl.setAttributeNode(oldAttr.cloneNode())
调试/序列化时查看原始属性信息Attr 包含 namespaceURI、prefix 等完整信息

示例:复制所有属性(包括 xmlns 声明)

function copyAttributes(fromEl, toEl) {
    for (let attr of fromEl.attributes) {
        // 自动处理普通属性和 xmlns 声明
        toEl.setAttributeNode(attr.cloneNode());
    }
}

6. 现代推荐做法 vs 传统 Attr 操作(对比表)

操作现代推荐方式(优先)老方式(不推荐)说明
获取属性值el.getAttribute(“id”)el.getAttributeNode(“id”).value更简单
设置属性el.setAttribute(“id”, “123”)let a=doc.createAttribute(“id”); a.value=”123″; el.setAttributeNode(a)太繁琐
删除属性el.removeAttribute(“id”)el.removeAttributeNode(attr)
检查是否存在el.hasAttribute(“id”)el.attributes.getNamedItem(“id”) != null
遍历所有属性for(let attr of el.attributes)同左现代方式更优雅

7. 关键结论(务必记住)

  1. 99% 的情况下,你不需要直接操作 Attr 对象,用 getAttribute / setAttribute 就够了。
  2. 唯一必须用 Attr 的场景:遍历 element.attributes(尤其是要保留 xmlns、xsi:schemaLocation 等命名空间声明时)。
  3. Attr 节点不属于文档树的子节点(不在 childNodes 中),它是元素的“附属品”。
  4. Attr 节点是可以被多个元素共享的(除非你克隆),但现代浏览器通常会自动隔离。

总结一句话:

Attr 对象是 XML DOM 中“属性”的真实节点表示,主要用于 element.attributes 遍历和精确复制命名空间声明,日常增删改查请直接使用 setAttribute / getAttribute / removeAttribute 即可。

掌握这一点,你就不会在处理 xmlnsxsi:schemaLocationxml:base 等特殊属性时掉坑里了。

文章已创建 2732

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部