Я анализирую HTML (через HAP) и теперь анализирую содержимое конкретной колонки таблицы для каждой строки (коллекция элементов TD)
Примечание. Не используется синтаксический анализатор HTML FSharp.Data, поскольку он не работает с HTMLкоторый содержит <Script>
код, который вызывает сбой селекторов CSS (известная проблема)
Тип, который я пытаюсь отобразить в строку данных (10 "столбцов" разных типов):
type DailyRow = { C0: string; C1: string; C2: int; C3: decimal; C4: string; C5: string; C6: int; C7: decimal; C8: decimal; C9: int }
Моя уродливая, но работающая функция, которая отображает положения столбцов в поле записи (да, все, что не анализируется правильно, должно взорваться):
let dailyRow = fun (record:DailyRow, column:int, node:HtmlNode) ->
printfn "dailyRow: Column %i has value %s" column node.InnerText
match column with
| 0 -> {record with C0 = node.InnerText }
| 1 -> {record with C1 = node.InnerText }
| 2 -> {record with C2 = (node.InnerText |> int) }
| 3 -> {record with C3 = Decimal.Parse(node.InnerText, NumberStyles.Currency) }
| 4 -> {record with C4 = node.InnerText }
| 5 -> {record with C5 = node.InnerText }
| 6 -> {record with C6 = Int32.Parse(node.InnerText, NumberStyles.AllowThousands) }
| 7 -> {record with C7 = Decimal.Parse(node.InnerText, NumberStyles.Currency) }
| 8 -> {record with C8 = Decimal.Parse(node.InnerText, NumberStyles.Currency) }
| 9 -> {record with C9 = (node.InnerText |> int) }
| _ -> raise (System.MissingFieldException("New Field in Chart Data Found: " + column.ToString()))
Некоторые тестовые коды:
let chartRow = { C0 = ""; C1 = ""; C2 = 0; C3 = 0.0M; C4 = "" ; C5 = ""; C6 = 0; C7 = 0.0M; C8 = 0.0M; C9 = 0 }
let columnsToParse = row.SelectNodes "td" // 1 row of 10 columns
let x = columnsToParse
|> Seq.mapi (fun i x -> dailyRow(chartRow, i, x))
Проблема, поскольку я передаю неизменяемую запись и получаю новую запись из функции dailyRow через Seq.mapi
(используя индекс для сопоставления с номером столбца), в итоге получится 10 записей, каждая с однойих значения свойства установлены.
В C # я бы просто передал dailyRow
объект ref'd и обновил бы его на месте, каков будет F # идиоматический способ обработки этого?