代码之家  ›  专栏  ›  技术社区  ›  Paul Fryer

如何用XElement检查元素的存在?

  •  3
  • Paul Fryer  · 技术社区  · 15 年前

    注意,在这段代码中,我试图检查rdfs:range element 在尝试选择之前。我这样做是为了避免在运行时出现可能的空引用异常。

        private readonly XNamespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
        private readonly XNamespace rdfs = "http://www.w3.org/2000/01/rdf-schema#";
        private readonly XElement ontology;
    
        public List<MetaProperty> MetaProperties
        {
            get
            {
                return (from p in ontology.Elements(rdf + "Property")
                        select new MetaProperty
                        {
                            About = p.Attribute(rdf + "about").Value,
                            Name = p.Element(rdfs + "label").Value,
                            Comment = p.Element(rdfs + "comment").Value,
                            RangeUri = p.Elements(rdfs + "range").Count() == 1 ?
                                p.Element(rdfs + "range").Attribute(rdf + "resource").Value :
                                null
                        }).ToList();
            }
        }
    

    这有点困扰我,我真正想做的是:

    p.HasElements(rdfs + "range") ?
        p.Element(rdfs + "range").Attribute(rdf + "resource").Value :
        null
    

    但是没有 HasElement(string elementName) 方法可用。

    2 回复  |  直到 14 年前
        1
  •  1
  •   abatishchev Karl Johan    14 年前

    基本相同,但更整洁

    return (from p in ontology.Elements(rdf + "Property") 
    let xRange = p.Element(rdfs + "range") 
    select new MetaProperty 
    { 
        About = p.Attribute(rdf + "about").Value, 
        Name = p.Element(rdfs + "label").Value, 
        Comment = p.Element(rdfs + "comment").Value, 
        RangeUri = xRange == null ? null : xRange.Attribute(rdf + "resource").Value 
    }).ToList(); 
    
        2
  •  7
  •   Jon Skeet    15 年前

    您可以使用:

    p.Elements(rdfs + "range").SingleOrDefault()
    

    它会回来的 null 如果没有元素。如果有多个匹配元素,它将抛出异常- FirstOrDefault()

    编辑:根据我的评论,利用从XAttribute到string的转换,还处理空值:

    return (from p in ontology.Elements(rdf + "Property") 
            select new MetaProperty 
                       { 
                           About = p.Attribute(rdf + "about").Value, 
                           Name = p.Element(rdfs + "label").Value, 
                           Comment = p.Element(rdfs + "comment").Value, 
                           RangeUri = (string) p.Elements(rdf + "range")
                                                .Attributes(rdf + "resource")
                                                .FirstOrDefault()
                        }).ToList(); 
    

    如果在很多地方都有相同的东西,那么可以编写一个扩展方法来很容易地封装它:

    public static XAttribute FindAttribute(this XElement element,
        XName subElement, XName attribute)
    {
        return element.Elements(subElement).Attributes(attribute).FirstOrDefault();
    }
    

    所以RangeUri位是:

    RangeUri = (string) p.FindAttribute(rdf + "range", rdf + "resource")