【问题标题】:determine if xml file contains data - c#确定xml文件是否包含数据-c#
【发布时间】:2009-09-07 12:32:47
【问题描述】:

我如何知道我的 XML 文件是否包含名称空间信息以外的数据:

一些文件包含以下内容:

<?xml version="1.0" encoding="UTF-8"?>

如果我遇到这样的文件,我想将文件放在错误目录中

【问题讨论】:

    标签: c#


    【解决方案1】:

    您可以使用 XmlReader 来避免 XmlDocument 的开销。在您的情况下,您将收到一个异常,因为缺少根元素。

    string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
    using (StringReader strReader = new StringReader(xml))
    {
        //You can replace the StringReader object with the path of your xml file.
        //In that case, do not forget to remove the "using" lines above.
        using (XmlReader reader = XmlReader.Create(strReader))
        {
            try
            {
                while (reader.Read())
                {
                }
            }
            catch (XmlException ex)
            {
                //Catch xml exception
                //in your case: root element is missing
            }
        }
    }
    

    您可以在检查第一个节点后在 while(reader.Read()) 循环中添加一个条件,以避免读取整个 xml 文件,因为您只想检查根元素是否丢失。

    【讨论】:

    • +1 但在 catch 块中捕获 XmlException 而不仅仅是 Exception。
    • 也可能只使用 XmlReader.Create('filename') 重载而不是传入 StringReader 以避免必须先将 xml 正文加载到内存中,否则如果任何......虽然我只是在我的第一杯咖啡上,所以带着一粒盐! :)
    • 我同意你的看法。在那种情况下,我只是使用 stringreader 来使用 itech 提供的 xml 示例。
    • 如果您只关心是否可以读取文件,您可以将其设为方法并返回 reader.Reader() 并在 XmlException 中返回 false;
    • 如果您只关心空的 XML 文档,您可以使用 reader.MoveToContent();而不是 while(reader.Read()) {}
    【解决方案2】:

    我认为唯一的方法是在尝试加载异常时捕获它,如下所示:

       try
        {
            System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
            doc.Load(Server.MapPath("XMLFile.xml"));
        }
        catch (System.Xml.XmlException xmlEx)
        {
            if (xmlEx.Message.Contains("Root element is missing"))
            {
                // Xml file is empty
            }
        }
    

    是的,有一些开销,但无论如何你都应该像这样执行健全性检查。你永远不应该相信输入,唯一可靠地验证它是 XML 的方法就是像对待 XML 一样对待它,看看 .NET 是怎么说的!

    【讨论】:

      【解决方案3】:

      XmlDocument xDoc = new XmlDocument();

      如果 (xDoc.ChildNodes.Count == 0) { // xml 文档为空 }

      如果 (xDoc.ChildNodes.Count == 1) { // 在 xml 文档中只有声明节点。 (如果你确定声明总是在开头}

      如果 (xDoc.ChildNodes.Count > 1) { // 有声明 + n 个节点(通常这个数是 2;声明 + 根节点) }

      【讨论】:

        【解决方案4】:

        没有试过这个……但应该可以。

        try
        {
            XmlDocument doc = new XmlDocument();
            doc.Load("test.xml");
        }
        catch (XmlException exc)
        {
            //invalid file
        }
        

        编辑:基于反馈 cmets

        对于大型 XML 文档,请参阅Thomas's 答案。这种方法可能存在性能问题。 但是,如果它是一个有效的 xml 并且程序想要处理它,那么这种方法似乎更好。

        【讨论】:

        • 我想过这个,但是加载 XML 和执行我的建议之间的开销有什么区别?这肯定更清楚,但我只是对性能感到好奇,尤其是对于大型 XML 文档 - 如果不需要它,为什么要加载 XML?
        • +1 Thomas,我同意您的观点,即不要将我的方法用于大型 XML 文档。但是,如果它是一个有效的 xml 并且程序想要处理它,那么这种方法似乎更好。
        • 确实如此。我认为您应该将其添加到您的帖子中,我也会添加与我的类似的内容。
        • PK - 这行不通。尝试加载文档后,您将立即收到异常。
        • 您对性能开销的看法是正确的——尤其是对于 >= 85K 大小的文档。但我敢打赌,张贴者需要更多地了解该文件的内容,而不是处理指令之外是否有任何数据(例如有效的 xml)。在这种情况下,XmlReader 将保持更平坦的内存模型,并提供轻松确定是否有效 xml 的好处。
        【解决方案5】:

        如果您不担心有效性,只需检查第一个之后是否有任何内容?>。我不完全确定 C# 语法(自从我使用它以来已经太久了),但是阅读文件,查找 ?> 的第一个实例,并查看该索引之后是否有任何内容。

        但是,如果您想稍后使用 XML 或想稍后处理 XML,您应该考虑 PK's answer 并将 XML 加载到 XmlDocument 对象中。但是,如果您有不需要处理的大型 XML 文档,那么像我这样的解决方案,将文件作为文本读取,可能会减少开销。

        【讨论】:

          【解决方案6】:

          您可以检查 xml 文档是否有节点(根节点)并检查该节点是否有内部文本或其他子节点。

          【讨论】:

            【解决方案7】:

            只要不关心 XML 文档的有效性,只想确保它有声明以外的标签,就可以使用简单的文本处理:

            var regEx = new RegEx("<[A-Za-z]");
            bool foundTags = false;
            string curLine = "";
            
            using (var reader = new StreamReader(fileName)) {
                while (!reader.EndOfStream) {
                   curLine = reader.ReadLine();
                   if (regEx.Match(curLine)) {
                       foundTags = true;
                       break;
                   }
                }
            }
            
            if (!foundTags) {
                // file is bad, copy.
            }
            

            请记住,文件可能无效的其他原因有一百万个,上面的代码将验证仅包含“

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-12-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-03-12
              • 1970-01-01
              • 2014-04-14
              • 1970-01-01
              相关资源
              最近更新 更多