如何在C#中正确验证svg字符串

本文关键字:验证 svg 字符串 | 更新日期: 2023-09-27 18:20:12

我正在尝试使用我制作的这个小util方法来验证给定的字符串是否是有效的svg:

public static bool IsValidSvg(string str) {
    try {
        var svg = XDocument.Load(new StringReader(str));
        return svg.Root.Name.LocalName.Equals("svg");
    } catch {
        return false;
    }
}

这适用于90%的情况,但例如,我有一个svg,它有一个如下的打开标签:

<svg version="1.1" id="Layer_2" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
 x="0px" y="0px" width="599.33398px" height="490.66748px" viewBox="0 0 599.33398 490.66748"
 enable-background="new 0 0 599.33398 490.66748" xml:space="preserve">

然后验证失败,因为它不知道ns_extend是什么…它抛出:

System.Xml.XmlException:引用的实体"ns_extend"不存在。第1行,位置53。

我该怎么绕过这个?svg渲染正确,所以它应该是一个有效的svg。。。

如何在C#中正确验证svg字符串

一个快速而肮脏的方法修复:

private static bool IsSvg(string input)
{
    try
    {
        using (var file = new FileStream(input, FileMode.Open, FileAccess.Read))
        using (var reader = new XmlTextReader(file) {XmlResolver = null})
            return reader.Read() && reader.Name.Equals("svg", StringComparison.InvariantCultureIgnoreCase);
    }
    catch
    {
        return false;
    }
}

通过将XmlResolver属性设置为null,读取器将忽略DTD引用。