如何捕获 SVG 解析错误?

How to catch an SVG parsing error?

我正在尝试为生成 SVG 路径作为字符串的代码编写单元测试(使用 qunit)。测试之一应该是那个东西是否实际上是有效的 SVG。

在 Chrome 浏览器控制台中,只需执行以下操作即可轻松测试:

$("<svg xmlns=\"http://www.w3.org/2000/svg\"><path d=\"asdsdsadas\" /></svg>")

这将失败并显示相应的错误消息:

Error: Invalid value for attribute d="asdsdsadas"

但是,它也returns这个无效的文件,就像它本来就没问题一样。

当我 运行 qunit 中的这段代码时,错误被打印到浏览器控制台中,但单元测试仍然成功,因为它实际上不是异常。我也没有成功抓住它。

我试过覆盖 console.error,但显然这个错误起源于更深层次,不关心 JavaScript 诡计。

有人知道如何正确识别此错误吗?

从字符串中捕获 svg 解析错误的正常方法是使用 DOMParser() 对象。

如果您将无效字符串传递给 parseFromString() 方法,那么 DOMParser 将 return 一个错误文档。

var invalidMarkup = "<svg xmlns=\"http://www.w3.org/2000/svg\"><path d\"M0,0\" /></svg>";
var oParser = new DOMParser();
var doc = oParser.parseFromString(invalidMarkup, 'image/svg+xml');

var failed = doc.documentElement.nodeName.indexOf('parsererror')>-1;

if(failed){
  snippet.log('failed to load the doc : '+doc.documentElement.nodeName);
  }
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

但是你在问题中给出的标记是有效的 svg+xml 标记。
解析器不会抱怨它。

var yourMarkup = "<svg xmlns=\"http://www.w3.org/2000/svg\"><path d=\"asdsdsadas\" /></svg>";
var oParser = new DOMParser();
var doc = oParser.parseFromString(yourMarkup, 'image/svg+xml');

var failed = doc.documentElement.nodeName.indexOf('parsererror') > -1;

if (failed) {
  snippet.log('failed to load the doc : ' + doc.documentElement.nodeName);
} else {
  snippet.log('success');
}
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Chrome 控制台告诉您的是它无法绘制 <path>.

d 属性中包含的整个段

Per specs,

The general rule for error handling in path data is that the SVG user agent shall render a ‘path’ element up to (but not including) the path command containing the first error in the path data specification.

因此,在您的具体情况下,不会呈现任何内容,但也不会抛出任何错误。

以编程方式检测此类错误的唯一方法是获取您的 path.pathSegList.length 并检查它是否与您添加到此属性中的段数相对应。

但是 IMO,您应该在生成值时直接测试您的值。