3 people like it.

XLinq for F#

Simple helper to ease building xml with XElement and XAttribute in F#

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
module Xml

open System
open System.Xml.Linq

[<NoComparison>]
type XmlContainer =
    | XmlElement of string * XmlContainer list
    | Attribute of string * obj
    | XmlValue of string

    static member Element(name: string, [<ParamArray>] 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"
module Xml
namespace System
namespace System.Xml
namespace System.Xml.Linq
Multiple items
type NoComparisonAttribute =
  inherit Attribute
  new : unit -> NoComparisonAttribute

--------------------
new : unit -> NoComparisonAttribute
union case XmlContainer.XmlElement: string * XmlContainer list -> XmlContainer
Multiple items
val string : value:'T -> string

--------------------
type string = String
type XmlContainer =
  | XmlElement of string * XmlContainer list
  | Attribute of string * obj
  | XmlValue of string
    override ToString : unit -> string
    static member Element : name:string * [<ParamArray>] children:XmlContainer [] -> XmlContainer
    static member Element : name:string * value:string -> XmlContainer
type 'T list = List<'T>
Multiple items
union case XmlContainer.Attribute: string * obj -> XmlContainer

--------------------
type Attribute =
  member Equals : obj:obj -> bool
  member GetHashCode : unit -> int
  member IsDefaultAttribute : unit -> bool
  member Match : obj:obj -> bool
  member TypeId : obj
  static member GetCustomAttribute : element:MemberInfo * attributeType:Type -> Attribute + 7 overloads
  static member GetCustomAttributes : element:MemberInfo -> Attribute[] + 15 overloads
  static member IsDefined : element:MemberInfo * attributeType:Type -> bool + 7 overloads
type obj = Object
union case XmlContainer.XmlValue: string -> XmlContainer
val name : string
Multiple items
type ParamArrayAttribute =
  inherit Attribute
  new : unit -> ParamArrayAttribute

--------------------
ParamArrayAttribute() : ParamArrayAttribute
val children : XmlContainer []
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
    interface IReadOnlyList<'T>
    interface IReadOnlyCollection<'T>
    interface IEnumerable
    interface IEnumerable<'T>
    member GetReverseIndex : rank:int * offset:int -> int
    member GetSlice : startIndex:int option * endIndex:int option -> 'T list
    member Head : 'T
    member IsEmpty : bool
    member Item : index:int -> 'T with get
    member Length : int
    ...
val ofArray : array:'T [] -> 'T list
val value : string
val x : XmlContainer
val fromContainer : (XmlContainer -> obj)
val container : XmlContainer
val children : XmlContainer list
Multiple items
type XElement =
  inherit XContainer
  new : name:XName -> XElement + 4 overloads
  member AncestorsAndSelf : unit -> IEnumerable<XElement> + 1 overload
  member Attribute : name:XName -> XAttribute
  member Attributes : unit -> IEnumerable<XAttribute> + 1 overload
  member DescendantNodesAndSelf : unit -> IEnumerable<XNode>
  member DescendantsAndSelf : unit -> IEnumerable<XElement> + 1 overload
  member FirstAttribute : XAttribute
  member GetDefaultNamespace : unit -> XNamespace
  member GetNamespaceOfPrefix : prefix:string -> XNamespace
  member GetPrefixOfNamespace : ns:XNamespace -> string
  ...

--------------------
XElement(name: XName) : XElement
XElement(other: XElement) : XElement
XElement(other: XStreamingElement) : XElement
XElement(name: XName, content: obj) : XElement
XElement(name: XName, [<ParamArray>] content: obj []) : XElement
type XName =
  member Equals : obj:obj -> bool
  member GetHashCode : unit -> int
  member LocalName : string
  member Namespace : XNamespace
  member NamespaceName : string
  member ToString : unit -> string
  static member Get : expandedName:string -> XName + 1 overload
XName.op_Implicit(expandedName: string) : XName
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
val value : obj
Multiple items
type XAttribute =
  inherit XObject
  new : other:XAttribute -> XAttribute + 1 overload
  member IsNamespaceDeclaration : bool
  member Name : XName
  member NextAttribute : XAttribute
  member NodeType : XmlNodeType
  member PreviousAttribute : XAttribute
  member Remove : unit -> unit
  member SetValue : value:obj -> unit
  member ToString : unit -> string
  member Value : string with get, set
  ...

--------------------
XAttribute(other: XAttribute) : XAttribute
XAttribute(name: XName, value: obj) : XAttribute
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...
val ofList : list:'T list -> 'T []
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Raw view Test code New version

More information

Link:http://fssnip.net/81C
Posted:3 years ago
Author:Vianney PHILIPPE
Tags: linq , linq-to-xml