当前位置: 首页 > news >正文

【为什么使用`new DOMParser`可以保持SVG命名空间】

为什么使用new DOMParser可以保持SVG命名空间:


一、命名空间基础概念

1. XML命名空间定义
<svg xmlns="http://www.w3.org/2000/svg"><!-- 此元素及其子元素属于SVG命名空间 --><rect x="10" y="20"/>
</svg>
  • xmlns属性:定义默认命名空间
  • 作用:避免元素名称冲突
2. DOM中的命名空间表示
const svgElem = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
console.log(svgElem.namespaceURI); // 输出: "http://www.w3.org/2000/svg"

二、DOMParser的工作原理

1. 解析过程分析
const parser = new DOMParser();
const doc = parser.parseFromString(svgString, "image/svg+xml");

关键步骤

  1. 根据MIME类型image/svg+xml初始化解析器
  2. 创建符合SVG规范的DOM树
  3. 自动处理命名空间声明
2. 命名空间处理机制
DOMParser Document 创建文档对象 设置文档类型为SVG 解析字符串时自动添加命名空间 返回带有正确命名空间的DOM树 DOMParser Document

三、对比不同解析方式

1. 错误方式:innerHTML
const div = document.createElement('div');
div.innerHTML = '<svg><rect x="10"/></svg>';
const svg = div.querySelector('svg');
console.log(svg.namespaceURI); // 输出: null (HTML命名空间)

问题

  • 在HTML文档上下文中解析
  • SVG元素被当作自定义HTML元素
2. 正确方式:DOMParser
const doc = new DOMParser().parseFromString('<svg><rect x="10"/></svg>', 'image/svg+xml'
);
const svg = doc.documentElement;
console.log(svg.namespaceURI); // 输出: "http://www.w3.org/2000/svg"

优势

  • 在独立文档中解析
  • 保留原始命名空间信息

四、命名空间保持的关键因素

1. MIME类型指定
// 正确指定MIME类型
parseFromString(content, 'image/svg+xml')// 错误示例(解析为HTML)
parseFromString(content, 'text/html')
2. 文档类型创建
// DOMParser内部实现伪代码
function parseFromString(string, mimeType) {const doc = createDocumentForType(mimeType);parseXML(string, doc);return doc;
}
  • 当mimeType为image/svg+xml时,创建SVG规范的文档
3. 元素创建规则
// 解析器创建元素时的逻辑
function createElement(tagName) {if (currentNamespace === SVG_NS) {return document.createElementNS(SVG_NS, tagName);}// ...其他命名空间处理
}

五、实际案例分析

1. 保留命名空间的重要性

示例代码

// 使用DOMParser解析
const doc = parser.parseFromString('<svg><foreignObject xmlns="http://www.w3.org/1999/xhtml"><div/></foreignObject></svg>','image/svg+xml'
);const div = doc.querySelector('div');
console.log(div.namespaceURI); // 输出: "http://www.w3.org/1999/xhtml"

说明

  • foreignObject内的div保持XHTML命名空间
  • 样式和事件处理正常
2. 命名空间错误的影响
// 错误解析后的元素
const svg = document.createElement('svg');
const rect = document.createElement('rect');
svg.appendChild(rect);console.log(rect.namespaceURI); // 输出: null
rect.setAttribute('x', '10'); // 属性可能无法生效

后果

  • CSS选择器失效(无法匹配SVG元素)
  • 部分属性无法被正确解析
  • 动画和交互功能异常

六、源码级解析(以Chromium为例)

1. DOMParser实现

源码位置third_party/blink/renderer/core/xml/dom_parser.cc

关键代码段

Document* DOMParser::parseFromString(const String& str,const String& type) {// 根据MIME类型创建文档Document* doc = CreateDocument(type,GetExecutionContext(),EnsureParserCreated(GetExecutionContext()->GetSecurityOrigin()));// 解析内容doc->SetContent(str);return doc;
}
2. SVG文档创建

源码位置third_party/blink/renderer/core/xml/document_init.cc

DocumentInit DocumentInit::Create() {if (MIMETypeRegistry::IsSVGMIMEType(mime_type)) {return DocumentInit::CreateSVG();}// ...其他类型处理
}

七、总结

为什么processSVG函数通过DOMParser可以保持命名空间

  1. 专用文档上下文
    DOMParser根据image/svg+xml MIME类型创建符合SVG规范的文档环境

  2. 元素创建规则
    在解析过程中自动使用createElementNS创建元素

  3. 命名空间继承机制
    子元素自动继承父元素的命名空间

  4. 属性处理一致性
    保留原始属性中的命名空间声明(如xlink:href)

  5. 标准化解析流程
    遵循XML解析规范,正确处理命名空间前缀

关键优势

  • 确保SVG元素被正确识别
  • 保留所有命名空间相关功能(如XLink引用)
  • 兼容各种SVG查看器和编辑器

验证方法

const doc = new DOMParser().parseFromString('<svg xmlns="http://www.w3.org/2000/svg"></svg>','image/svg+xml'
);
console.log(doc.documentElement.namespaceURI); 
// 输出: "http://www.w3.org/2000/svg"

附录:一、DOMParser 保持命名空间的核心机制

1. MIME 类型驱动解析
// 关键代码
const doc = new DOMParser().parseFromString(svgString, "image/svg+xml");
  • MIME 类型识别image/svg+xml 明确告知解析器处理 SVG 内容
  • 文档类型创建:生成符合 SVG 规范的 XML 文档对象
2. 命名空间自动继承
<!-- 解析后的 DOM 结构 -->
<svg xmlns="http://www.w3.org/2000/svg"><rect x="10" y="20"/> <!-- 自动继承 SVG 命名空间 -->
</svg>
3. 元素创建规则

解析器内部使用 createElementNS 方法:

// 伪代码实现
function createElement(tagName) {return document.createElementNS('http://www.w3.org/2000/svg', tagName);
}

二、命名空间保持验证

1. 元素级验证
const svg = doc.documentElement;
console.log(svg.namespaceURI); 
// 输出:"http://www.w3.org/2000/svg"const rect = doc.querySelector('rect');
console.log(rect.namespaceURI);
// 输出:"http://www.w3.org/2000/svg"
2. 属性级验证
const useElem = doc.querySelector('use');
console.log(useElem.getAttributeNS('http://www.w3.org/1999/xlink', 'href'
));
// 正确获取 xlink:href 属性

三、与其他解析方式的对比

解析方式命名空间保持元素识别适用场景
innerHTML作为普通元素简单HTML片段
createElementNS准确识别动态创建元素
DOMParser准确识别完整文档解析
XMLSerializer序列化保留文档转换输出

四、实现原理图示

根据MIME类型
使用createElementNS
原始SVG字符串
DOMParser解析
创建SVG文档对象
解析元素
创建SVG元素
保留命名空间属性
生成完整DOM树

五、关键优势总结

  1. 精准元素识别:浏览器正确渲染SVG元素
  2. 属性完整性:保留xlink:href等命名空间属性
  3. 样式兼容:CSS选择器正确匹配
  4. 脚本操作可靠:DOM API可正常操作元素
  5. 数据交换无损:序列化后保持原始结构

六、代码验证示例

<script>
function testNamespace() {const svgString = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><use xlink:href="#icon"/></svg>`;// 使用DOMParser解析const doc = new DOMParser().parseFromString(svgString, "image/svg+xml");const useElem = doc.querySelector('use');// 验证命名空间console.log('SVG命名空间:', doc.documentElement.namespaceURI === 'http://www.w3.org/2000/svg');// 验证跨命名空间属性console.log('XLink属性读取:',useElem.getAttributeNS('http://www.w3.org/1999/xlink', 'href') === '#icon');
}testNamespace();
// 输出: true, true
</script>

结论DOMParser 通过 MIME 类型识别、命名空间感知的元素创建和属性处理机制,确保 SVG 文档的命名空间完整性,这是其他解析方式无法替代的核心优势。

相关文章:

【为什么使用`new DOMParser`可以保持SVG命名空间】

为什么使用new DOMParser可以保持SVG命名空间&#xff1a; 一、命名空间基础概念 1. XML命名空间定义 <svg xmlns"http://www.w3.org/2000/svg"><!-- 此元素及其子元素属于SVG命名空间 --><rect x"10" y"20"/> </svg>…...

【DL】浅谈深度学习中的知识蒸馏 | 输出层知识蒸馏

目录 一 核心概念与背景 二 输出层知识蒸馏 1 教师模型训练 2 软标签生成&#xff08;Soft Targets&#xff09; 3 学生模型训练 三 扩展 1 有效性分析 2 关键影响因素 3 变体 一 核心概念与背景 知识蒸馏&#xff08;Knowledge Distillation, KD&#xff09;是一种模…...

应急响应(linux 篇,以centos 7为例)

一、基础命令 1.查看已经登录的用户w 2.查看所有用户最近一次登录&#xff1a;lastlog 3.查看历史上登录的用户还有登录失败的用户 历史上所有登录成功的记录 last /var/log/wtmp 历史上所有登录失败的记录 Lastb /var/log/btmp 4.SSH登录日志 查看所有日志&#xff1a;…...

EasyRTC:智能硬件适配,实现多端音视频互动新突破

一、智能硬件全面支持&#xff0c;轻松跨越平台障碍 EasyRTC 采用前沿的智能硬件适配技术&#xff0c;无缝对接 Windows、macOS、Linux、Android、iOS 等主流操作系统&#xff0c;并全面拥抱 WebRTC 标准。这一特性确保了“一次开发&#xff0c;多端运行”的便捷性&#xff0c…...

堆和栈的区别

堆和栈 不同点&#xff1a; 内存分配方式不同&#xff1a; 栈&#xff1a;栈上的内存是自动分配和释放的&#xff0c;通常用于存储函数调用过程中的局部变量、调用参数和使用的寄存器状态等信息。堆&#xff1a;堆上的内存是动态分配的&#xff0c;程序在运行时可以根据需要分…...

【信息系统项目管理师】专业英语重点词汇大汇总

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 一、信息和信息系统重要词汇汇总1.Computer(计算机)重要词汇2.Information system(信息系统)重要词汇3.Software Engineering(软件工程)重要词汇4.Network(网络)相关重要词汇5.信息安全重要词汇6.Electronic Co…...

CV -- YOLOv8 图像分割(GPU环境)

目录 参考视频&#xff1a; 标注 JSON转为TXT 训练 验证 参考视频&#xff1a; 使用 Yolov8 自定义数据集进行图像分割_哔哩哔哩_bilibili 标注 数据集&#xff1a; 我使用的是一些苹果数据集&#xff0c;可以在我的csdn资源中下载&#xff1a; https://download.csdn.net/do…...

Cherry-Studio下载安装教程,AI面向开发者的工具或平台(付安装包)

文章目录 一、Cherry Studio是什么&#xff1f;二、功能特点 一、Cherry Studio是什么&#xff1f; Cherry Studio 是一款开源跨平台的多模型服务桌面客户端&#xff0c;集成超 300 个大语言模型&#xff0c;内置 300 多个预配置 AI 助手&#xff0c;支持多格式文件处理、全局…...

【Javascript Day19】BOM

目录 BOM对象的方法 定时器方法 短信验证码案例 计时器元素动画 同步代码和异步代码 location对象 跳转查询页面参数 跳转多查询参数 BOM对象的方法 // window.alert("提示");// window 中提供的方法和属性&#xff0c;可以在省略window对象的情况下直接调用…...

git 操作 已经 commit 但是没有 push 怎么办

前言&#xff1a; 在操作commit后发现提交错了分支&#xff0c;直接切换分支是不行的&#xff0c;只能先取消commit的代码才能切换分支&#xff0c;因此记录一下git的操作 如果你已经执行了 git commit 但还没有进行 git push&#xff0c;可以通过以下几种方式撤回或修改提交…...

在 macOS 的 ARM 架构上按住 Command (⌘) + Shift + .(点)。这将暂时显示隐藏文件和文件夹。

在 macOS 的 ARM 架构&#xff08;如 M1/M2 系列的 Mac&#xff09;上&#xff0c;设置 Finder&#xff08;访达&#xff09;来显示隐藏文件夹的步骤如下&#xff1a; 使用快捷键临时显示隐藏文件&#xff1a; 在Finder中按住 Command (⌘) Shift .&#xff08;点&#xff…...

【核心算法篇二十】《DeepSeek符号回归:让AI化身「数学神探」破解数据背后的宇宙公式》

“宇宙最不可理解之处,就是它居然可以被理解。”——爱因斯坦 如果让AI来续写这句话,或许会是:"数据最迷人的地方,在于它总能用数学公式讲出故事。"今天我们要聊的DeepSeek符号回归技术,就是教AI从杂乱数据中自动发现精妙数学规律的「黑魔法」。全程高能预警,建…...

如何在 Visual Studio Code 中使用 DeepSeek R1 和 Cline?

让我们面对现实吧&#xff1a;像 GitHub Copilot 这样的 AI 编码助手非常棒&#xff0c;但它们的订阅费用可能会在你的钱包里烧一个洞。进入 DeepSeek R1 — 一个免费的开源语言模型&#xff0c;在推理和编码任务方面可与 GPT-4 和 Claude 3.5 相媲美。将它与 Cline 配对&#…...

PHP旅游门票预订系统小程序源码

&#x1f30d; 旅游门票预订系统&#xff1a;一站式畅游新体验&#xff0c;开启您的梦幻旅程 &#x1f31f; 一款基于ThinkPHPUniapp精心雕琢的旅游门票预订系统&#xff0c;正翘首以待&#xff0c;为您揭开便捷、高效、全面的旅游预订新篇章&#xff01;它超越了传统预订平台…...

在项目中调用本地Deepseek(接入本地Deepseek)

前言 之前发表的文章已经讲了如何本地部署Deepseek模型&#xff0c;并且如何给Deepseek模型投喂数据、搭建本地知识库&#xff0c;但大部分人不知道怎么应用&#xff0c;让自己的项目接入AI模型。 文末有彩蛋哦&#xff01;&#xff01;&#xff01; 要接入本地部署的deepsee…...

notepad++右键菜单不见了

卸载时没点击完成&#xff0c;又重新安装了一个&#xff0c;最终导致了一些bug&#xff0c;导致右键没有notepad菜单。 解决方式&#xff1a; 新建一个register.reg文件&#xff0c;加入以下代码&#xff0c;然后双击执行即可 代码说明&#xff1a;Open with Notepad 是右…...

如何用ollama快速布署deepseek-r1大模型

deepseek在春节期间因为特朗普的一番发言而在中国已几乎人尽皆知&#xff0c;热度到了连90高寿的老父亲都向我推荐这个中国产的AI大模型&#xff0c;而且它是开源的&#xff01;我试验了下&#xff0c;用ollama也可以快速度安装布署deepseek-r1大模型。本想写篇文章来介绍下dee…...

python-leetcode 36.二叉树的最大深度

题目&#xff1a; 给定一个二叉树root,返回其最大深度 二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数 方法一&#xff1a;深度优先搜索 知道了左子树和右子树的最大深度l和r&#xff0c;那么该二叉树的最大深度即为:max(l,r)1 而左子树和右子树的最大深…...

MySQL事务的特性和隔离级别

一、事务的特性 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败 事务的有以下四个特性&#xff08;acid&#xff09;&#xf…...

Oracle视图(基本使用)

视图 视图是通过定制的方式显示一个或者多个表的数据。 视图可以视为“虚拟表”或“存储的查询”。 视图的优点&#xff1a; 提供了另外一种级别的表安全性隐藏了数据的复杂性简化了用户的SQL命令隔离基表结构的改变通过重命名列&#xff0c;从另一个角度提供数据。 视图里…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...