Although I am not a PowerShell fan, I do like one feature of PowerShell. You can easily go from file system to registry. PowerShell treat file system and registry are same thing. I am afraid I have to face some Azure Virtual Machine management tasks in the future and I need to prepare in advance.
The following Computational Expression (CE) is a way to design an embedded language like PowerShell. I do not want to risk my computer's registry so I choose the File system and XML file. If you use cd "my path", it goes to either folder, file, or XML file's node or attribute.
the file system is like
and the XML file is
Tweet to fsharp
The following Computational Expression (CE) is a way to design an embedded language like PowerShell. I do not want to risk my computer's registry so I choose the File system and XML file. If you use cd "my path", it goes to either folder, file, or XML file's node or attribute.
the file system is like
and the XML file is
// Learn more about F# at http://fsharp.net
// See the 'F# Tutorial' project for more help.
open System
open System
open System.Xml.Linq
type UnifiedType =
| Directory of string
| XMLFile of string
| Node of XElement * UnifiedType
| Attribute of string * XAttribute * UnifiedType
let rec getElement currentType (path:string list) =
match path with
| [] ->
currentType
| head::tail ->
let node =
match currentType with
| Directory(dir) ->
let dirs = System.IO.Directory.GetDirectories(dir)
match dirs |> Seq.tryFind (fun n -> n.EndsWith head) with
| Some n -> Directory(System.IO.Path.Combine(n))
| _ ->
let files = System.IO.Directory.GetFiles(dir, "*.xml")
match files |> Seq.tryFind (fun file ->
String.Compare(System.IO.Path.GetFileName(file), head, true)=0) with
| Some n -> XMLFile(n)
| _ -> failwithf "cannot find %s" dir
| XMLFile (name) ->
let doc = XDocument.Load(name)
match (doc.Descendants()) |> Seq.tryFind (fun n -> n.Name.LocalName=head) with
| Some n -> Node(n, currentType)
| _ -> failwithf "cannot find %s" name
| Node(node, fn) ->
match (node.Descendants()) |> Seq.tryFind (fun n -> n.Name.LocalName=head) with
| Some n -> Node(n, fn)
| _ ->
match (node.Attributes()) |> Seq.tryFind(fun n -> n.Name.LocalName=head) with
| Some n -> Attribute(n.Name.LocalName, n, fn)
| _ -> failwithf "cannot find %s" node.Name.LocalName
| Attribute(name, value, fn) ->
failwithf "cannot find %s" name
getElement node tail
let setValue point (v:string) =
match point with
| Attribute (name, value, XMLFile(fn)) ->
value.Value <- v
value.Document.Save(fn)
| _ -> ()
type ExtendedFileSystem(startPoint:UnifiedType) =
member this.Yield( () ) = startPoint
[<CustomOperation("cd")>]
member this.GoDown(point:UnifiedType, id:string) =
getElement point [id]
[<CustomOperation("set")>]
member this.Set(point:UnifiedType, v:string) =
setValue point v
point
member this.Run(point:UnifiedType) =
fun () -> point
let fileSystem = ExtendedFileSystem(Directory(@".\"))
let fs =
fileSystem {
cd "Data"
cd "Xml"
cd "XmlFile1.xml"
cd "Xml"
cd "Data"
cd "A"
set "17" }
printfn "%A" ( fs() )
ignore <| System.Console.ReadKey()
Tweet to fsharp
No comments:
Post a Comment