Notice in this code I am trying to check for the existence of the rdfs:range element before trying to select it. I do this to avoid a possible null reference exception at runtime.
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-schem开发者_如何学JAVAa#";
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();
}
}
This is kinda bugging me, what I really want to do is something like this:
p.HasElements(rdfs + "range") ?
p.Element(rdfs + "range").Attribute(rdf + "resource").Value :
null
However there is no HasElement(string elementName)
method available.
I guess I could create a method extension to do this, but am wondering if there is something already built in or if there are other ways to do this?
You can use:
p.Elements(rdfs + "range").SingleOrDefault()
which will return null
if there are no elements. It will throw an exception if there's more than one matching element - FirstOrDefault()
will avoid this if it's not the desired behaviour.
EDIT: As per my comment, and taking advantage of the conversion from XAttribute to string also handling nulls:
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();
If you have the same thing in many places, you could write an extension method to encapsulate that very easily:
public static XAttribute FindAttribute(this XElement element,
XName subElement, XName attribute)
{
return element.Elements(subElement).Attributes(attribute).FirstOrDefault();
}
So the RangeUri bit would be:
RangeUri = (string) p.FindAttribute(rdf + "range", rdf + "resource")
Same basic thing, but neater
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();
精彩评论