代码之家  ›  专栏  ›  技术社区  ›  Dean Harding

比element.Elements(“Whatever”).First()更好的解决方案?

  •  1
  • Dean Harding  · 技术社区  · 15 年前

    我有这样一个XML文件:

    <SiteConfig>
      <Sites>
        <Site Identifier="a" />
        <Site Identifier="b" />
        <Site Identifier="c" />
      </Sites>
    </SiteConfig>
    

    该文件是用户可编辑的,所以我想提供合理的错误消息,以防我不能正确解析它。我可能可以为它写一个.xsd,但对于一个简单的文件来说,这似乎有点过分了。

    所以不管怎样,当查询 <Site>

    var doc = XDocument.Load(...);
    
    var siteNodes = from siteNode in 
                      doc.Element("SiteConfig").Element("Sites").Elements("Site")
                    select siteNode;
    

    但问题是如果用户没有包含 <SiteUrls> 它只会抛出一个 NullReferenceException

    另一种可能就是 Elements() 到处都是,而不是 Element() ,但如果再加上 Attribute() ,例如,在以下情况下:

    var siteNodes = from siteNode in 
                      doc.Elements("SiteConfig")
                         .Elements("Sites")
                         .Elements("Site")
                    where siteNode.Attribute("Identifier").Value == "a"
                    select siteNode;
    

    Attributes("xxx").Value )

    元素() (和) 属性() null

    我可以写我自己的版本 元素() 属性()

    2 回复  |  直到 15 年前
        1
  •  2
  •   Mark Byers    15 年前

    您可以将所需的功能实现为扩展方法:

    public static class XElementExtension
    {
        public static XElement ElementOrThrow(this XElement container, XName name)
        {
            XElement result = container.Element(name);
            if (result == null)
            {
                throw new InvalidDataException(string.Format(
                    "{0} does not contain an element {1}",
                    container.Name,
                    name));
            }
            return result;
        }
    }
    

    你需要一些类似的东西 XDocument . 然后像这样使用:

    var siteNodes = from siteNode in 
        doc.ElementOrThrow("SiteConfig")
           .ElementOrThrow("SiteUrls")
           .Elements("Sites")
        select siteNode;
    

    然后你会得到这样一个例外:

    SiteConfig does not contain an element SiteUrls
    
        2
  •  0
  •   Darin Dimitrov    15 年前

    XPathSelectElements

    using System;
    using System.Linq;
    using System.Xml.Linq;
    using System.Xml.XPath;
    
    class Program
    {
        static void Main()
        {
            var ids = from site in XDocument.Load("test.xml")
                      .XPathSelectElements("//SiteConfig/Sites/Site")
                      let id = site.Attribute("Identifier")
                      where id != null
                      select id;
            foreach (var item in ids)
            {
                Console.WriteLine(item.Value);
            }
        }
    }
    

    想到的另一件事是定义一个XSD模式,并根据这个模式验证XML文件。这将产生有意义的错误消息,如果文件是有效的,您可以解析它没有问题。

    推荐文章