module Xml open System open System.Xml.Linq [] type XmlContainer = | XmlElement of string * XmlContainer list | Attribute of string * obj | XmlValue of string static member Element(name: string, [] children: XmlContainer[]) : XmlContainer = XmlElement (name, children |> List.ofArray) static member Element(name: string, value: string) : XmlContainer = XmlElement (name, [ XmlValue value ]) override x.ToString() = let rec fromContainer container : obj = match container with | XmlElement (name, children) -> XElement(XName.op_Implicit name, children |> List.map fromContainer) :> obj | Attribute (name, value) -> XAttribute(XName.op_Implicit name, value) :> obj | XmlValue value -> value :> obj match x with | XmlElement (name, children) -> XElement(XName.op_Implicit name, children |> List.map fromContainer |> Array.ofList).ToString() | Attribute (name, value) -> XAttribute(XName.op_Implicit name, value).ToString() | XmlValue value -> value // usage open type Xml.XmlContainer Element( "builds", Element( "build", Element("statusText", "ignored build with missing attributes") ), Element( "build", Attribute("id", failedBuild.Id.Value), Attribute("buildTypeId", failedBuild.BuildTypeId.Value), Attribute("statusText", failedBuild.Status.Value) ) ).ToString() |> printfn "%s"