2010-07-28 3 views
3

Обратите внимание, что в этом коде я пытаюсь проверить наличие элемента rdfs: range перед тем, как выбрать его. Я делаю это, чтобы исключить возможное исключение с использованием NULL во время выполнения.Как проверить наличие элемента с XElement?

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) доступный метод.

Я думаю, я мог бы создать расширение метода для этого, но мне интересно, есть ли что-то уже встроенное или есть ли другие способы сделать это?

ответ

1

То же самое, но аккуратное

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(); 
+0

Да, это опрятно. Мне нравится, думаю, я буду использовать его для проверки других свойств. –

7

Вы можете использовать:

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

который будет возвращать null, если нет никаких элементов. Он будет генерировать исключение, если имеется более одного соответствующего элемента - FirstOrDefault() избежит этого, если это не желаемое поведение.

EDIT: В соответствии с моим комментарием, и воспользовавшись преобразования из XAttribute в строку также обработки нулей:

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") 
+0

Полезно знать, я забыл о функциях FirstOrDefault. Единственная потенциальная проблема, которую я вижу в этом, заключается в том, что я не могу просто вызвать .Attribute, потому что я не знаю, вернет ли она значение null или нет. –

+1

@Paul: Правда. Возможно, вы захотите написать свой собственный метод расширения 'AttributeOrNull', который принимает нули соответствующим образом. В качестве альтернативы вы можете использовать «Элементы (rdfs +« range »). Атрибуты (rdf +« resource »). FirstOrDefault()' –

Смежные вопросы