用xdocument手动拼svg最直接,需显式声明xmlns命名空间、避免自闭合svg标签、设置width/height属性并注意viewbox配合;复杂图形推荐skiasharp.svg,但需确认api兼容性并防范xss风险。

用 XmlDocument 或 XDocument 手动拼 SVG 标签最直接
SVG 本质是 XML,C# 里不需要第三方库就能生成。用 XDocument 构建结构清晰、可读性强,适合简单图表(如图标、流程图、坐标系标记)。注意命名空间必须显式声明:xmlns="http://www.w3.org/2000/svg",否则浏览器会当作普通 XML 不渲染。
常见错误:漏掉 xmlns 属性,或把 <svg></svg> 写成自闭合形式(<svg></svg>),部分浏览器不认。
- 根节点必须带
xmlns,且不能省略结束标签 - 宽高建议用
width和height属性,而非 CSS;若需响应式,加viewBox - 中文文本要确保字体存在,或嵌入
<style></style>设font-family: sans-serif
XDocument svg = new XDocument(
new XElement("svg",
new XAttribute("xmlns", "http://www.w3.org/2000/svg"),
new XAttribute("width", "200"),
new XAttribute("height", "100"),
new XElement("rect",
new XAttribute("x", "10"),
new XAttribute("y", "20"),
new XAttribute("width", "80"),
new XAttribute("height", "40"),
new XAttribute("fill", "#4CAF50")
),
new XElement("text",
new XAttribute("x", "10"),
new XAttribute("y", "15"),
new XText("Hello SVG")
)
)
);
svg.Save("output.svg");用 SkiaSharp 渲染复杂图形再导出为 SVG
如果需要路径绘制、贝塞尔曲线、渐变填充或复用 Canvas 逻辑,SkiaSharp.Svg 是更稳妥的选择。它把绘图指令转成 SVG 元素,自动处理坐标变换和样式封装,避免手写 XML 出错。
注意:不是所有 Skia 绘图 API 都支持 SVG 后端(比如某些滤镜、阴影),调用前查文档确认 SKSvgSurface 是否支持该操作。
- 初始化时指定
SKSvgSurface,不是SKSurface - 导出内容靠
surface.Canvas绘制,最后用svgSurface.SvgDocument.ToString()获取字符串 - 文字测量和换行需手动处理,
SKPaint.MeasureText返回的是像素宽度,非 SVG 的 em 单位
生成含交互的 SVG(如 <script></script> 或事件)要防 XSS
若动态插入 JavaScript 片段(例如点击弹窗、hover 变色),直接拼接字符串极易引入 XSS。C# 里没有“安全的 SVG 脚本模板”,必须严格过滤用户输入。
典型风险:把用户昵称直接写进 <text onclick="alert('<user>')"></text>,<user></user> 若含 " 或 就会破坏结构。
- 禁用内联脚本,改用
<script type="application/ecmascript"></script>外链(但多数环境不支持) - 纯前端交互建议用 CSS
:hover,服务端只输出静态 SVG - 必须支持 JS 时,对所有动态值做
WebUtility.HtmlEncode,并移除javascript:、on\w+=等模式
文件体积与兼容性:别盲目嵌入字体或位图
SVG 文件看似小,但嵌入 Base64 位图或整套 @font-face 字体后可能暴涨数 MB,且 iOS Safari 对嵌入字体支持不稳定。
生成时优先用系统字体(font-family: Arial, sans-serif),真需定制字体,只嵌入子集(如仅包含中文常用字),并确认 font-face 的 src 使用 url(data:...) 且 MIME 类型正确(font/woff2)。
- 位图用
<image href="data:image/png;base64,..."></image>时,Base64 字符串不能换行 - IE 11 不支持
viewBox缩放下的em单位文字,统一用px - 导出后用浏览器打开验证:右键「查看页面源代码」确认结构合法,再检查控制台有无解析错误
实际项目中,90% 的 SVG 生成需求用 XDocument 就够了;只有当图形逻辑已基于 SkiaSharp 实现,或需精确像素对齐时,才值得引入 SkiaSharp.Svg。手动生成最容易被忽略的是 viewBox 与 width/height 的配合——没设 viewBox,缩放就只是拉伸位图,不是真正矢量缩放。










