F# - Recursive Read XML Data

Deat alls,

Я пытаюсь работать с этими несколькими строками кода, но я действительно не знаю, почему 'myTreeNodes' список TreeNodes сбрасывается во время вызова 'extractData' процедуры.

Кажется, что я соблюдал все необходимые ограничения и хорошую практику, но что-то... я упустил!

Заранее большое спасибо за любое ваше предложение

ANN

Код

    let GetFactors =        
        let errorHeader = "Gasket Factor - List Retrieve"
        let doc = new XmlDocument()
        let myTreeNodes = List<TreeNode>.Empty 

        let readData (xmlNode:XmlNode) (treeNodes:List<TreeNode>) =
            match xmlNode.Name with
            |   "GasketFactors" -> 
                    let attribs = xmlNode.Attributes
                    if (attribs.Count > 0) then
                        let name = GetStringData "Version" attribs
                        printfn "GASKET FACTORS VERSION: '%s'" name
            |   "Gasket" -> 
                    let attribs = xmlNode.Attributes                         
                    if (attribs.Count > 0) then
                        let name = GetStringData "Type" attribs
                        let mainNode = new TreeNode(name)
                        let treeNodes = mainNode :: treeNodes
                        printfn " - Type: %s " name
            |   "Data" -> 
                    let attribs = xmlNode.Attributes 
                    if (attribs.Count > 0) then
                        let parent = List.head treeNodes
                        let gskType = parent.Name 
                        let gskSource = GetStringData "Source" attribs
                        let gskSubType = GetStringData "SubType" attribs
                        let gskMaterialGroup = GetStringData "Group" attribs
                        let gskMaterial = GetStringData "Material" attribs
                        let gskMaterialFiller = GetStringData "Filler" attribs
                        let gskMaterialLayers = GetStringData "Layers" attribs
                        let gsk_m = 
                            let value = GetStringData "m" attribs
                            0.0
                        let gsk_y = 
                            let value = GetStringData "y" attribs
                            0.0
                        let gskFactors = new Factors(gsk_m, gsk_y)
                        let gskService = GetStringData "Service" attribs
                        let gskUserNote = GetStringData "Note" attribs
                        let gskShow = GetBoolData "Show" attribs
                        let newGasket = new Gasket(gskSource, gskType, gskSubType,
                                                   gskMaterial, gskMaterialGroup, gskMaterialFiller, gskMaterialLayers,
                                                   gskFactors, new Geometry(),
                                                   gskService, gskUserNote, gskShow) 
                        let childNode = new TreeNode(gskSubType)
                        childNode.Tag <- newGasket
                        parent.Nodes.Add(childNode) |> ignore
                        printfn "     - Sub Type: %s " (newGasket.ToString())
            |   _ -> 
                    printfn "%A" xmlNode

        let rec extractData (xmlNode:XmlNode) (treeNodes:List<TreeNode>) =
            if (xmlNode <> null) then
                match xmlNode.NodeType with
                |   XmlNodeType.Element -> 
                        readData xmlNode treeNodes
                        printfn "{TEXT: %s}" xmlNode.Value
                        if (xmlNode.HasChildNodes) then
                            extractData xmlNode.FirstChild treeNodes
                        else
                            let next = xmlNode.NextSibling
                            let parent = xmlNode.ParentNode 
                            if (next <> null) then
                                extractData next treeNodes    
                            else
                                extractData parent treeNodes  
                |   XmlNodeType.Text | XmlNodeType.CDATA ->
                        printfn "{TEXT: %s}" xmlNode.Value
                        extractData xmlNode.NextSibling treeNodes
                |   XmlNodeType.Comment ->
                        printfn "{COMMENT: %s}" xmlNode.Value
                        extractData xmlNode.NextSibling treeNodes
                |   XmlNodeType.ProcessingInstruction | XmlNodeType.XmlDeclaration ->
                        printfn "{DECLARATION: %s = %s}" xmlNode.Name xmlNode.Value
                        extractData xmlNode.NextSibling treeNodes
                |   _ -> 
                        printfn "{OTHER: %s = %s}" xmlNode.Name xmlNode.Value 
                        extractData xmlNode.NextSibling treeNodes
            else
                ()

        try
            doc.Load( Resources.GasketXMLFactorsPath )
        with
        | ex -> failwith (errorHeader + ": Not Possible to Load!" + ex.ToString())            
        extractData doc.FirstChild myTreeNodes
        myTreeNodes

XML Source

{GasketFactors Version="1.0.0.0"}

{Gasket Type="Self-Energizing"}

{Data Source="ASME" SubType="Welded" m="0.00" y="0.0 psi" /}

{Data Source="ASME" SubType="Any" m="0.00" y="0.0 psi" /}

{/Gasket}

{Gasket Type="Vegetable Fibers"}

{Data Source="ASME" SubType="Any" Material="Any" m="1.75" y="1100.0 psi" /}

{/Gasket}

{/GasketFactors}
1
задан Artefacto 22 August 2010 в 16:53
поделиться

1 ответ

Я не углублялся глубоко, но если

let myTreeNodes = List<TreeNode>.Empty 

- это F # list <'T>, тогда он неизменяемый, и когда вы добавляете элемент в список - вы создаете новый список вместо изменения исходного. Вы можете либо на каждом шаге брать список источников и возвращать измененную версию, либо использовать изменяемую коллекцию, например System.Collections.Generic.List <'T> или System.Collections.Generic.LinkedList < 'T> для накопления изменений.

2
ответ дан 2 September 2019 в 21:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: