代码之家  ›  专栏  ›  技术社区  ›  Steve Cooper

检查格式正确的XML而不使用try/catch?

  •  25
  • Steve Cooper  · 技术社区  · 15 年前

    有人知道如何在不使用类似这样的东西的情况下检查字符串是否包含格式良好的XML吗? XmlDocument.LoadXml() 在Try/Catch块中?我得到的输入可能是XML,也可能不是XML,我希望代码能够识别输入可能不是XML,而不依赖于try/catch,无论是速度还是一般原则,即非异常情况不应引发异常。我目前有这样做的代码;

    private bool IsValidXML(string value)
        {
            try
            {
                // Check we actually have a value
                if (string.IsNullOrEmpty(value) == false)
                {
                    // Try to load the value into a document
                    XmlDocument xmlDoc = new XmlDocument();
    
                    xmlDoc.LoadXml(value);
    
                    // If we managed with no exception then this is valid XML!
                    return true;
                }
                else
                {
                    // A blank value is not valid xml
                    return false;
                }
            }
            catch (System.Xml.XmlException)
            {
                return false;
            }
        }
    

    但似乎不需要尝试/捕获。这个异常在调试过程中引起了欢乐,因为每当我检查一个字符串时,调试程序都会在这里中断,“帮助”我解决棘手的问题。

    9 回复  |  直到 9 年前
        1
  •  23
  •   Jon Skeet    15 年前

    我不知道没有异常的验证方法,但是您可以将调试器设置更改为仅中断 XmlException 如果它是未经处理的-这应该可以解决您的即时问题,即使代码仍然不完美。

    要执行此操作,请转到调试/异常…/公共语言运行时异常并查找System.xml.xmlException,然后确保只勾选了“用户未处理”选项(未引发)。

        2
  •  7
  •   Greg Finzer    11 年前

    史提夫,

    我们有一个第三方偶然地向我们发送了JSON而不是XML。以下是我实现的:

    public static bool IsValidXml(string xmlString)
    {
        Regex tagsWithData = new Regex("<\\w+>[^<]+</\\w+>");
    
        //Light checking
        if (string.IsNullOrEmpty(xmlString) || tagsWithData.IsMatch(xmlString) == false)
        {
            return false;
        }
    
        try
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(xmlString);
            return true;
        }
        catch (Exception e1)
        {
            return false;
        }
    }
    
    [TestMethod()]
    public void TestValidXml()
    {
        string xml = "<result>true</result>";
        Assert.IsTrue(Utility.IsValidXml(xml));
    }
    
    [TestMethod()]
    public void TestIsNotValidXml()
    {
        string json = "{ \"result\": \"true\" }";
        Assert.IsFalse(Utility.IsValidXml(json));
    }
    
        3
  •  5
  •   Matthew Flaschen    15 年前

    这是一种合理的方法,除了isNullOrEmpty是多余的(loadXML可以很好地解决这个问题)。如果你真的保持是空的,那么就做如果(!string.isNullOrEmpty(value))。

    不过,基本上,调试器是问题所在,而不是代码。

        4
  •  4
  •   Steve Cooper    14 年前

    添加 [System.Diagnostics.DebuggerStepThrough] 属性 IsValidXml 方法。这将禁止调试程序捕获XmlException,这意味着您可以打开捕获第一个更改异常的功能,并且不会调试此特定方法。

        5
  •  2
  •   golfalot    9 年前

    使用注意事项 XmlDocument 因为可以沿着 <0>some text</0> 使用 XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(object) 没有 引发异常。

    数字元素名称不是有效的XML,在我的示例中,在我尝试将xmldoc.innerText写入XML的SQL Server数据类型之前,没有发生错误。

    这就是我现在验证的方式,并抛出异常
    XmlDocument tempDoc = XmlDocument)JsonConvert.DeserializeXmlNode(formData.ToString(), "data"); doc.LoadXml(tempDoc.InnerXml);

        6
  •  1
  •   dandan78 Tom Cool    14 年前

    xmlTextReader类是 xmlReader的实现,以及 提供快速、性能良好的分析器。它 强制执行XML必须 成形良好。它不是一个 验证或非验证分析器 因为它没有DTD或架构 信息。它可以在 块,或从 溪流。

    还有另一篇我已经添加了要阅读的代码的msdn文章中的一个例子。 XML流的全部内容。

    string str = "<ROOT>AQID</ROOT>";
    XmlTextReader r = new XmlTextReader(new StringReader(str));
    try
    {
      while (r.Read())
      {
      }
    }
    finally
    {
      r.Close();
    }
    

    来源: http://bytes.com/topic/c-sharp/answers/261090-check-wellformedness-xml

        7
  •  0
  •   Lipis    12 年前

    我不同意问题在于调试器。一般来说,对于非特殊情况,应避免例外。这意味着如果有人在寻找 IsWellFormed() 它根据输入是否为格式良好的XML返回true/false,不应在此实现中引发异常,无论是否捕获和处理异常。

    异常非常昂贵,在正常成功执行期间不应遇到异常。例如,编写一个方法来检查文件是否存在,并使用file.open,并在文件不存在的情况下捕获异常。这将是一个糟糕的实施。相反 File.Exists() 应该使用它(希望它的实现不会简单地在某个方法周围放置一个try/catch,该方法会引发一个异常,如果该文件不存在,我确信它不存在)。

        8
  •  0
  •   hello_earth    11 年前

    就我的2美分——关于这一点有各种各样的问题,大多数人都同意“垃圾进-垃圾出”的事实。我不同意这一点,但我个人发现了以下快速而肮脏的解决方案,尤其是在处理来自第三方的XML数据的情况下,这些数据根本不容易与您通信。它并没有避免使用try/catch——但它使用的粒度更细,因此在无效XML字符的数量不那么大的情况下,它会有所帮助。我为每个父元素使用了xmltextreader及其方法readchars(),这是不执行格式良好检查的命令之一,如readinner/outerxml。因此,当read()存根出现在父节点上时,它是read()和readchars()的组合。当然,这是因为我可以假定XML的基本结构是正常的,但是某些节点的内容(值)可以包含一些特殊字符,这些字符没有被&…;等效的替换…(我在某个地方找到了一篇关于这个的文章,但现在找不到源链接)

        9
  •  -2
  •   toddmo    10 年前

    我的两分钱。这很简单,遵循一些常见的约定,因为它是关于解析…

    public bool TryParse(string s, ref XmlDocument result)
    {
        try {
            result = new XmlDocument();
            result.LoadXml(s);
            return true;
        } catch (XmlException ex) {
            return false;
        }
    }
    
    推荐文章