I am trying to parse a directory of XML files and then select the value of particular attribute if a given node is present. Am not able to understand the reason for the compilation error that the following F# is causing.
open System
open System.IO
open System.Xml
open System.Xml.XPath
open System.Xml.Linq
let configRootDirectory = @"C:\dir"
let relativeProductDir = @"relDir"
let ExtractConfiguredCalculator (productConfigFile:string) =
let xmlNavigator = XPathDocument(productConfigFile).CreateNavigator()
let node = xmlNavigator.SelectSingleNode(@"Product/SupportedRisk/Risk[@type='PV']")
node.GetAttribute("methodology", "")
let configFile = Directory.GetFiles(Path.Combine(configRootDirectory, relativeProductDir), @"*.xml")
|> Seq.cast<string>
|> Seq.iter(fun configFileName -> ExtractConfiguredCalculator(configFileName))
|> Seq.filter(fun configuredCalculatorNode -> configuredCalculatorNode != null)
|> Seq.iter(fun calculator -> Console.WriteLine(calculator))
The above snippet is from the code that I am experimenting with in LinqPad. The error message seen is as below.
This expression was expected to have type unit but here has type string
Update
Trying to get more f#-ish. Please suggest if something can be improved.
let configFile =
Directory.GetFiles(Path.Combine(configRootDirectory, relativeProductDir), @"*.xml")
|> Seq.map(fun configFileName ->
let xmlNavigator = XPathDocument(configFileName).CreateNavigator()
let node = xmlNavigator.SelectSingleNode(@"Product/SupportedRisk/Risk[@type='PV']")
match node with
| null -> "PV not configured"
| _ ->
let attributeValue = node.GetAttribute("methodology", "")
match attributeValue with
| null -> "Calculator not configured"
| _ -> attributeValue)
|> Seq.iter (printfn "%s")
You have to change the first
Seq.itertoSeq.mapto return a sequence which is required by the subsequentSeq.filter.I have several comments though:
Seq.castis redundant sinceDirectory.GetFilesreturnsstring [].Seq.mapandSeq.filtertogether, you could always replace them bySeq.choose.printfnis a more F#ish way of printing thanConsole.WriteLine.Here is an improved version: