Parsování cfg souboru v C#

Giovanna

Parsování cfg souboru v C#
« kdy: 18. 04. 2015, 00:38:55 »
Dobrý den, mám následující:
Kód: [Vybrat]
    public enum NodeType
    {
        Unknown,
        BeginBracket,
        EndBracket,
        Node,
        NodeWithComment,
        ValueNode,
        ValueNodeWithComment,
        StandaloneComment,
        EmptyLine
    }

    public class Program
    {
        public static string fileName;

        public static string pathInFile;
        public static string newValue;

        public class CfgNode
        {
            private NodeType nodeType;
            private string nodeName;
            private string nodeValue;
            private string nodeComment;

            private List<CfgNode> childNodes;


            protected CfgNode()
            {
                childNodes = new List<CfgNode>();
            }
           

            public CfgNode(NodeType nodeType, string nodeName, string nodeValue, string nodeComment)
            {
                this.nodeType = nodeType;
                this.nodeName = nodeName;
                this.nodeValue = nodeValue;
                this.nodeComment = nodeComment;
            }

            protected void AddNode(CfgNode cfgNode)
            {
                childNodes.Add(cfgNode);
            }
        }

        public class CfgDocument : CfgNode
        {
            private string fileName;

            public CfgNode DocumentRoot;

            public CfgDocument()
                : base ()
            {
                DocumentRoot = this;
            }

            public bool Load(string fileName)
            {
                bool retVal = true;

                this.fileName = fileName;

                try
                {
                    using (StreamReader sr = new StreamReader(fileName))
                    {
                        while (!sr.EndOfStream)
                        {

                            string line = sr.ReadLine();

                            NodeType nodeType;
                            string nodeName;
                            string nodeValue;
                            string nodeComment;

                            if (ResolveNodeType(line, out nodeType, out nodeName, out nodeValue, out nodeComment))
                            {
                                switch (nodeType)
                                {
                                    case NodeType.Node:
                                        {
                                            AddNode(new CfgNode(nodeType, nodeName, nodeValue, nodeComment));
                                            break;
                                        }


                                }
                            }
                            else
                            {
                                retVal = false;
                                break;
                            }

                        }
                    }
                }
                catch (Exception ex)
                {
                    retVal = false;
                }

                return retVal;
            }

            private bool ResolveNodeType(string sourceLine, out NodeType nodeType, out string nodeName, out string nodeValue, out string nodeComment)
            {
                char[] hashSeparator = {'#'};
                char[] assignmentSeparator = {'='};

                nodeType = NodeType.Unknown;
                nodeName = string.Empty;
                nodeValue = string.Empty;
                nodeComment = string.Empty;

                sourceLine = sourceLine.Trim();

                if (sourceLine == "")
                {
                    nodeType = NodeType.EmptyLine;

                    //Console.WriteLine("EMPTYLINE");

                    return true;

                }

                if (sourceLine.StartsWith("{"))
                {
                    nodeType = NodeType.BeginBracket;

                    //Console.WriteLine("BEGINBRACKET");

                    return true;
                }

                if (sourceLine.StartsWith("}"))
                {
                    nodeType = NodeType.EndBracket;

                    //Console.WriteLine("ENDBRACKET");

                    return true;
                }

                if (sourceLine.StartsWith("#"))
                {
                    nodeType = NodeType.StandaloneComment;
                    nodeComment = sourceLine.Split(hashSeparator)[1];

                    //Console.WriteLine("COMMENT:" + nodeComment.Trim());

                    return true;
                }


                if (sourceLine.Contains(assignmentSeparator[0]))
                {
                    nodeType = NodeType.ValueNode;
                    string[] sourceLineParts = sourceLine.Split(assignmentSeparator);
                    nodeName = sourceLineParts[0].Trim();

                    //Console.Write("NODENAME:" + nodeName);

                    if (sourceLineParts.Length > 1)
                    {
                        string[] assigmentsWithComment = sourceLineParts[1].Split(hashSeparator);
                        nodeValue = assigmentsWithComment[0].Trim();

                        //Console.Write(", VALUE:" + nodeValue);

                        if (assigmentsWithComment.Length > 1)
                        {
                            nodeType = NodeType.ValueNodeWithComment;
                            nodeComment = assigmentsWithComment[1].Trim();

                            //Console.Write(", COMMENT:" + nodeComment);
                        }

                    }
                    //Console.WriteLine();

                    return true;
                }

                if (!sourceLine.Contains(assignmentSeparator[0]))
                {
                    string[] nodesWithComment = sourceLine.Split(hashSeparator);

                    nodeName = nodesWithComment[0].Trim();

                    if (nodesWithComment.Length > 1)
                    {
                        nodeType = NodeType.NodeWithComment;
                        //Console.Write("NODE:" + nodeName);
                        //Console.Write(", COMMENT:" + nodesWithComment[1].Trim());
                    }
                    else
                    {
                        nodeType = NodeType.Node;
                        //Console.Write("NODE:" + nodesWithComment[0].Trim());
                    }

                    //Console.WriteLine();

                    return true;
                }

                return false;
            }
        }

jde o parsování cfg souboru a vytvoření jeho objektové reprezentace kvůli vnořeným blokům, v podstatě jako XmlDokument, ale ten nechci použít.

Nevím, jestli jsem z toho OOP zmatený, ale v sekci:

Kód: [Vybrat]
                                switch (nodeType)
                                {
                                    case NodeType.Node:
                                        {
                                            AddNode(new CfgNode(nodeType, nodeName, nodeValue, nodeComment));
                                            break;
                                        }


                                }

mi vadí, že bych měl mít konstruktor s parametry a AddNode veřejnou. Přál bych si, abych ve třídě CfgNode měl veřejné jen gettery.

Vložený kód je samozřejmě zatím pouze rozpracovaný.

Děkuji za jakoukoliv poučku.
« Poslední změna: 18. 04. 2015, 18:42:41 od Petr Krčmář »


Kit

Re:Pomoc pri OOP C#
« Odpověď #1 kdy: 18. 04. 2015, 12:53:59 »
Právě gettery a settery by měly zůstat privátní kvůli zapouzdření. Konstruktory naopak kromě speciálních případů bývají veřejné.

Kaiaphas

Re:Pomoc pri OOP C#
« Odpověď #2 kdy: 18. 04. 2015, 16:03:42 »
Jestli jsem to dobře pochopil tak vám jde o to, že ten kdo bude konfiguraci konzumovat nemá vědět o tom, že pochází z nějakého XML a jak vlastně byla vytvořena.

To se řeší pomocí interfacu. Tzn. vytvoříte interface, který bude popisovat váš konfig pomocí getterů. Pak vytvoříte třídu, která bude daný interface implementovat. Tato třída navíc bude implementovat svůj konstruktor a setter metody. Funkce, která vám bude vracet tento konfigurační objekt potom bude mít nadeklarováno, že vrací ten váš interface, ale uvnitř funkce budete samozřejmě vytvářet objekt z vaší konkrétní třídy.

Snad jsem vás dobře pochopil a popsal to srozumitelně.