svg本质是xml文档,需严格遵循xml语法规范,包括根节点声明、标签闭合、命名空间xmlns、大小写敏感、字符编码与实体转义等,否则解析失败。

SVG本质就是XML文档
SVG不是某种独立的图形格式,它直接基于XML语法定义图形元素。一个合法的.svg文件,用文本编辑器打开就是标准XML:有根节点<svg></svg>、嵌套的<circle></circle>或<path></path>、属性用双引号包裹、必须闭合标签(<rect></rect>或<rect></rect>都行,但<rect></rect>不闭合会解析失败)。
常见错误现象:XML parse error: Unexpected end of file——多半是某个标签忘了闭合,或属性值里混进了未转义的&、。
- 所有SVG元素都是XML元素,支持
xml:space="preserve"控制空白处理 - 命名空间必须声明:
<svg xmlns="http://www.w3.org/2000/svg"></svg>,缺了这个,浏览器可能当作普通XML而不渲染 - 不能省略
xmlns就直接在HTML里写<svg><circle cx="10"></circle></svg>——虽然现代浏览器常宽容,但XML校验器会报错
内联SVG在HTML中为什么有时不生效
把SVG代码直接粘进HTML,看似简单,实则受HTML解析规则干扰。浏览器对<svg></svg>的处理分两层:HTML解析器先按HTML规则切分标签,再把内容交给SVG渲染器。
典型问题:<svg><use href="#icon"></use></svg>不显示图标——因为HTML解析器把href当成HTML属性,而SVG要求的是xlink:href(旧规范)或href(SVG 2,需xmlns:xlink或现代上下文)。
- 在HTML中使用
<use></use>,推荐写成<use href="#icon"></use>,但确保父<svg></svg>在同个文档且ID存在;外部符号需用<use href="sprite.svg#icon"></use> -
<script></script>块里操作SVG元素时,document.getElementById("my-circle")能取到,但getElementsByClassName返回的NodeList可能包含文本节点(换行缩进),需过滤 - HTML不区分大小写,但XML区分:
<circle></circle>在SVG中无效,必须小写<circle></circle>
XML实体与字符编码的实际影响
SVG作为XML,必须遵守字符编码声明。如果文件保存为UTF-8但没声明,或声明了UTF-8却含GBK字节,浏览器解析会卡在第一个非法字节,后续图形全丢。
错误信息示例:XML Parsing Error: not well-formed,定位行往往是中文文字或版权符号©所在行。
- 文件开头强烈建议加声明:
<?xml version="1.0" encoding="UTF-8"?>,哪怕HTML中嵌入也无害 - 特殊字符必须转义:
©、可用,但©直接写也行(UTF-8下);必须写成<code><,否则被当标签开始 - CSS样式里写
content: "©";没问题,但SVG的<text>©</text>必须确保文件编码和声明一致,否则变乱码方块
DOM操作SVG元素的几个硬约束
用JavaScript操作SVG,不能套用HTML DOM那一套直觉。比如innerHTML在SVG元素上基本不可靠,appendChild接受的必须是SVG命名空间下的节点。
常见错误:document.createElement("circle")创建的是HTML元素,插入SVG后不渲染;el.innerHTML = "<circle cx="10"></circle>"在某些浏览器里静默失败。
- 创建SVG元素必须用
document.createElementNS("http://www.w3.org/2000/svg", "circle") - 设置属性优先用
el.setAttributeNS(null, "cx", "10"),而非el.cx = 10(后者不触发渲染更新) - 监听事件如
click可以,但input、change这类表单事件对SVG原生元素无效









