public Maybe<IGraph> MaybeParse(XDocument graph)
{
var @return = Maybe<IGraph>.Nothing;
try
{
var mgid = graph.Root.MaybeXAttributeValue("id", xa => (GraphId)(string)xa);
var mns = from nse in graph.Root.Elements("ns")
let mnamespace = nse.MaybeXAttributeValue("ns", xa => (Namespace)(string)xa)
from ne in nse.Elements("n")
let mid = ne.MaybeXAttributeValue("id", xa => (NodeId)(string)xa)
let mc = ne.MaybeXElement(xe => xe.Elements("c").Single())
let mh =
from c in mc
from h in c.MaybeXAttributeValue("h", xa => xa.Value)
select h
let mcontent =
from c in mc
from content in c.MaybeXElementValue(xe => xe, xe => xe.Value)
select content
let exs0 = (new[]
{
mid.Exception,
mnamespace.Exception,
mc.Exception,
mh.Exception,
mcontent.Exception,
}).Where(ex => ex != null).Distinct().ToArray()
select exs0.Any()
? Maybe<INodeContent>.NothingWithException(exs0.SingleOrDefault() ?? new AggregateException(exs0))
: Maybe<INodeContent>.Something(new NodeContent(mid.Value, mnamespace.Value, mcontent.Value, mh.Value));
Func<XElement, bool> hasId = xe =>
xe.Attribute("id") != null;
Func<XElement, IEnumerable<XElement>> childrenWithId = xe =>
xe.Elements().Where(xee => xee.Attribute("id") != null);
var maps = (from a in graph.Descendants().Where(hasId)
let nid = (NodeId)(Guid)a.Attribute("id")
from b in childrenWithId(a)
let mnid = (NodeId)(Guid)b.Attribute("id")
group mnid by nid).ToDictionary(z => z.Key, z => z.AsEnumerable()).AsReadOnly();
var exs = mns.Select(z => z.Exception).StartWith(mgid.Exception).Where(ex => ex != null).ToArray();
if (exs.Any())
{
@return = Maybe<IGraph>.NothingWithException(exs.SingleOrDefault() ?? new AggregateException(exs));
}
else
{
@return = Maybe<IGraph>.Something(this.Create(mgid.Value, mns.ToDictionary(z => z.Value.NodeId, z => z.Value).AsReadOnly(), maps));
}
}
catch (Exception ex)
{
@return = Maybe<IGraph>.NothingWithException(ex);
}
return @return;
}