2

XMLファイルのディレクトリを解析し、特定のノードが存在する場合は特定の属性の値を選択しようとしています。次のF#が原因でコンパイルエラーが発生した理由を理解できません。

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))

上記のスニペットは、LinqPadで実験しているコードからのものです。表示されるエラーメッセージは次のとおりです。

This expression was expected to have type     unit     but here has type     string   

更新 より多くのf#っぽさを取得しようとしています。何か改善できるかどうか提案してください。

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")
4

2 に答える 2

6

後続のに必要なシーケンスを返すには、最初のをに変更するSeq.iter必要があります。Seq.mapSeq.filter

私はいくつかのコメントがあります:

  • Seq.castDirectory.GetFilesを返すので冗長string []です。
  • 一緒に持っているときはSeq.mapSeq.filterいつでもそれらを。に置き換えることができますSeq.choose
  • printfnよりもF#ishの印刷方法ですConsole.WriteLine

改善されたバージョンは次のとおりです。

let configFile = 
        Directory.GetFiles(Path.Combine(configRootDirectory, relativeProductDir), @"*.xml")    
        |> Seq.choose (fun configFileName -> 
                            let config = ExtractConfiguredCalculator(configFileName)
                            if config <> null then Some config else None)
        |> Seq.iter (printfn "%s")
于 2012-07-10T16:52:47.497 に答える
4

への最初の呼び出しはにするSeq.iter必要がありますSeq.mapExtractConfiguredCalculatorを返しますstringSeq.iter、関数がを返すことを期待していますunit

于 2012-07-10T16:52:20.297 に答える