예제 #1
0
 private string EncodeNodePath(SharpNode node, bool shortForm)
 {
     if (shortForm)
     {
         if (node.IsAttributeNode)
         {
             return(string.Format("  {0}", node.Name));
         }
         else if (node.IsExpandedValueNode)
         {
             return("  ");
         }
         else
         {
             return(string.Format("  ./{0}", node.Name));
         }
     }
     else
     {
         if (node.Path.EndsWith("/#"))
         {
             return(node.Path.Substring(0, node.Path.Length - 2));
         }
         return(node.Path);
     }
 }
예제 #2
0
        public SharpNodeRow CreateNodeRow(SharpNode node)
        {
            if (node.IsValueNode)
            {
                SharpValue value;

                if (AdditionalInfo.TryGetValue("DefaultValue", out value))
                {
                    return(new SharpValueRow(node, value.Value)
                    {
                        QueryPath = QueryPath
                    });
                }

                return(new SharpValueRow(node, null)
                {
                    QueryPath = QueryPath
                });
            }

            return(new SharpNodeRow(node)
            {
                QueryPath = QueryPath
            });
        }
예제 #3
0
        public SharpNode CreateNode()
        {
            var node = new SharpNode
            {
                Name        = SharpNode.GetNodeName(Path),
                Index       = Index,
                Path        = Path,
                IsValueNode = IsValueNode,
                ValueType   = ValueType,
                NodeType    = NodeType,
            };

            SharpValue value;

            if (AdditionalInfo.TryGetValue("Format", out value))
            {
                node.Format = value.Value.ToString();
            }

            if (!node.IsValueNode && AdditionalInfo.TryGetValue("DefaultValue", out value))
            {
                node.DefaultValue = value;
            }

            return(node);
        }
예제 #4
0
 internal SharpObjectList(SharpObject parent, string name, SharpRowCursor source, SharpNode node = null, bool useCache = false)
 {
     _parent   = parent;
     _name     = name;
     _source   = source;
     _useCache = useCache;
     _node     = node;
 }
예제 #5
0
 public SharpNodeMapColumn(SharpNode node, int width = -1, int offset = 0)
 {
     Node      = node;
     Width     = width;
     Offset    = offset;
     Index     = node.Index;
     ValueType = node.ValueType;
 }
예제 #6
0
        private string EncodeNode(SharpNode node, bool shortForm = false, bool schemaOnly = false, bool includeIndex = false)
        {
            StringBuilder sb = new StringBuilder();

            if (_nodeSchemaHistory.Contains(node.Index))
            {
                sb.Append(EncodeNodePath(node, shortForm));
            }
            else
            {
                if (schemaOnly)
                {
                    sb.Append("$");
                    if (includeIndex)
                    {
                        sb.Append(node.Index);
                    }

                    sb.Append(" = ");
                }

                sb.Append(EncodeNodePath(node, shortForm));

                if (node.ValueType != SharpValueType.None || node.NodeType != SharpNodeType.Any)
                {
                    sb.Append("~");

                    if (node.NodeType != SharpNodeType.Any)
                    {
                        sb.Append(node.NodeType.ToString());
                        if (node.ValueType != SharpValueType.None)
                        {
                            sb.Append(" ");
                        }
                    }

                    if (node.ValueType != SharpValueType.None)
                    {
                        sb.Append(node.ValueType.ToString());
                    }
                }

                if (!string.IsNullOrEmpty(node.Format))
                {
                    sb.Append(string.Format("{{{0}}}", node.Format));
                }

                if (schemaOnly && node.DefaultValue != null && node.DefaultValue.Value != null)
                {
                    sb.Append(string.Format(" := {0}", node.DefaultValue.Value));
                }

                _nodeSchemaHistory.Add(node.Index);
            }

            return(sb.ToString());
        }
예제 #7
0
        private void WriteNodeRow(SharpNodeRow row)
        {
            if (row.Node.PackageName.ToLower() != _lastPackage)
            {
                WritePackage(row.Node.PackageName);
            }

            _writer.WriteLine(EncodeNode(row.Node));
            _lastParentNode = row.Node;
        }
        public void Add(SharpNode node)
        {
            if (node.Parent == null)
            {
                AddParents(node);
            }

            node.IntializeNode(this, _currentPackage, _nextIndex++);

            _currentPackage.Add(node.Path, node);
            _nodes.Add(node.Index, node);
            node.UpdateNodeLinks();
        }
예제 #9
0
 public SharpValueRow(SharpNode node, IEnumerable <object> values)
 {
     RowType = SharpRowType.Value;
     Node    = node;
     if (values == null)
     {
         Values.Add(null);
     }
     else
     {
         Values.AddRange(values);
     }
 }
예제 #10
0
        public List <SharpNode> PathTo(SharpNode ancestor)
        {
            var result = new List <SharpNode>();

            var node = Parent;

            while (node != null && node != ancestor)
            {
                result.Insert(0, node);
                node = node.Parent;
            }

            return(result);
        }
예제 #11
0
 public SharpMetaNodeRow(SharpNode source)
 {
     Index     = source.Index;
     Path      = source.Path;
     NodeType  = source.NodeType;
     ValueType = source.ValueType;
     if (!string.IsNullOrEmpty(source.Format))
     {
         AdditionalInfo["Format"] = new SharpValue(source.Format);
     }
     if (source.DefaultValue != null)
     {
         AdditionalInfo["DefaultValue"] = new SharpValue(source.DefaultValue);
     }
 }
예제 #12
0
        private void AddParents(SharpNode node)
        {
            string path = node.GetParentPath();

            if (!string.IsNullOrEmpty(path))
            {
                var parent = _currentPackage.GetNode(path);
                if (parent == null)
                {
                    Add(new SharpNode()
                    {
                        Path = path, Name = SharpNode.GetNodeName(path)
                    });
                }
            }
        }
예제 #13
0
        public void Insert(SharpNode node)
        {
            if (node.Parent == null)
            {
                AddParents(node);
            }

            node.IntializeNode(this, _currentPackage);

            if (node.Index > _nextIndex)
            {
                _nextIndex = node.Index + 1;
            }

            _currentPackage.Add(node.Path, node);
            _nodes.Add(node.Index, node);

            node.UpdateNodeLinks();
        }
예제 #14
0
        public List <SharpNode> PathFrom(SharpNode ancestor)
        {
            if (Parent == null)
            {
                return(new List <SharpNode>());
            }

            SharpNodeStack stack = new SharpNodeStack();
            SharpNode      start = Parent;

            if (IsValueNode)
            {
                var nodePath = Path;
                if (nodePath.EndsWith("/#"))
                {
                    nodePath = nodePath.Substring(0, nodePath.Length - 2);
                }
                if (nodePath == Parent.Path)
                {
                    start = Parent.Parent;
                }
            }

            if (start == null || ancestor == start || !ancestor.HasDescendant(start))
            {
                return(new List <SharpNode>());
            }

            stack.Enqueue(start);
            while (stack.Top != ancestor)
            {
                if (stack.Top.Parent == null || stack.Top == stack.Top.Parent)
                {
                    break;
                }

                stack.Enqueue(stack.Top.Parent);
            }

            return(stack.ToList());
        }
예제 #15
0
        public SharpNode GetOrCreateNode(List <string> nodePath, bool isLeafNode, SharpNode parent = null)
        {
            var path = SharpNode.GetNodePath(nodePath, isLeafNode);
            var node = GetNode(path);

            if (node != null)
            {
                return(node);
            }

            node = new SharpNode
            {
                Path   = path,
                Name   = nodePath.Last(),
                Parent = parent
            };

            node.IsValueNode = node.Name.StartsWith("@") || isLeafNode;

            Add(node);
            return(node);
        }
예제 #16
0
        private void OpenFile(string filename, string nodePath, SharpRowReader rowReader)
        {
            if (!string.IsNullOrEmpty(nodePath))
            {
                var node = _nodes.GetNode(nodePath);
                if (node == null)
                {
                    _nodes.Add(new SharpNode
                    {
                        Path = nodePath,
                        Name = SharpNode.GetNodeName(nodePath)
                    });
                }
            }

            _stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
            _rows   = new SharpRowStream
            {
                Nodes        = _nodes,
                StreamNode   = string.IsNullOrEmpty(nodePath) ? null : _nodes.GetNode(nodePath),
                StreamSource = rowReader(_stream, _nodes)
            };
        }
예제 #17
0
        public void UpdateNodeLinks()
        {
            SharpNode parent = null;

            if (IsValueNode && !IsSingleValueNode)
            {
                parent = GetNodes().Select(x => x.Parent).FirstOrDefault();
            }
            else
            {
                if (IsLeafNode)
                {
                    parent = Package.GetNode(GetRootPath());
                }

                if (parent == null)
                {
                    parent = Package.GetNode(GetParentPath(Path));
                }
            }

            Parent = parent;
            UpdateAncestors();
        }
예제 #18
0
 public bool HasDescendant(SharpNode node)
 {
     return(Descendants.Contains(node.Index));
 }
예제 #19
0
        private void AddObject(string nodePath, IDictionary <string, object> item, List <SharpNodeRow> rows)
        {
            var node = _nodes.GetNode(nodePath);

            if (node == null)
            {
                node = new SharpNode
                {
                    Path = nodePath,
                    Name = SharpNode.GetNodeName(nodePath)
                };
                _nodes.Add(node);
            }

            rows.Add(new SharpNodeRow(node));

            // Object members are written to rows in alphabetical order in the following groups:
            //   1. Attributes
            //   2. Value Members
            //   3. Object Members
            //   4. Final Object Member (Many / Only / Last)

            List <string> fieldKeys = new List <string>();
            List <string> objKeys   = new List <string>();

            foreach (var key in item.Keys)
            {
                if (key.Length > 0 && key[0] == '@')
                {
                    var memberPath = string.Format("{0}/{1}", nodePath, key);
                    AddObjectMember(memberPath, key, item[key], null, rows);
                }
                else if (item[key] is IDictionary <string, object> || item[key] is IEnumerable <IDictionary <string, object> > )
                {
                    objKeys.Add(key);
                }
                else
                {
                    fieldKeys.Add(key);
                }
            }

            foreach (var key in fieldKeys)
            {
                var memberPath = string.Format("{0}/{1}", nodePath, key);
                AddObjectMember(memberPath, key, item[key], null, rows);
            }

            string lastKey = null;

            foreach (var key in objKeys)
            {
                var memberPath = string.Format("{0}/{1}", nodePath, key);
                var memberNode = _nodes.GetNode(memberPath);
                if (lastKey == null && memberNode != null && (memberNode.NodeType == SharpNodeType.Many || memberNode.NodeType == SharpNodeType.Only))
                {
                    lastKey = key;
                    continue;
                }
                AddObjectMember(memberPath, key, item[key], memberNode, rows);
            }

            if (lastKey != null)
            {
                var memberPath = string.Format("{0}/{1}", nodePath, lastKey);
                AddObjectMember(lastKey, memberPath, item[lastKey], null, rows);
            }
        }
예제 #20
0
 public SharpNodeRow(SharpNode node)
 {
     RowType = SharpRowType.Node;
     Node    = node;
 }
예제 #21
0
        public override IEnumerable <SharpRow> GetRows(SharpNode node = null)
        {
            if (node == null && _streamSource != null)
            {
                AddRange(_streamSource);

                foreach (var row in DequeueInsertRows())
                {
                    yield return(row);
                }

                _streamSource = null;
            }

            if (_streamSource == null || node == null)
            {
                yield break;
            }

            List <SharpRow> rows             = new List <SharpRow>();
            var             streamEnumerator = _streamSource.GetEnumerator();

            while (streamEnumerator.MoveNext())
            {
                var nodeRow = streamEnumerator.Current as SharpNodeRow;
                if (nodeRow == null)
                {
                    continue;
                }

                if (nodeRow.Node == node || !node.HasDescendant(nodeRow.Node))
                {
                    if (rows.Count > 0)
                    {
                        AddRange(rows, insertParentNodes: true, skipFirstParentRow: true);
                        rows.Clear();
                        foreach (var row in DequeueInsertRows())
                        {
                            yield return(row);
                        }
                    }

                    if (nodeRow.Node == node)
                    {
                        rows.Add(nodeRow);
                    }
                    continue;
                }

                rows.Add(nodeRow);
            }

            if (rows.Count > 0)
            {
                AddRange(rows, insertParentNodes: true, skipFirstParentRow: true);
                rows.Clear();
                foreach (var row in DequeueInsertRows())
                {
                    yield return(row);
                }
            }
        }
예제 #22
0
 public void Add(string name, SharpNode node)
 {
     _index[name] = node;
 }
예제 #23
0
        private void AddObjectMember(string memberPath, string key, object value, SharpNode node, List <SharpNodeRow> rows)
        {
            var objectList = value as SharpObjectList;

            if (objectList != null)
            {
                if (objectList.HasOnlyValue)
                {
                    AddObjectMember(memberPath, "", objectList.GetValueList(), node, rows);
                    return;
                }
            }

            var memberList = value as IEnumerable <IDictionary <string, object> >;

            if (memberList != null)
            {
                var memberListNode = node ?? _nodes.GetNode(memberPath);
                if (memberListNode == null)
                {
                    memberListNode = new SharpNode
                    {
                        Path     = memberPath,
                        Name     = SharpNode.GetNodeName(memberPath),
                        NodeType = SharpNodeType.Repeated
                    };
                    _nodes.Add(memberListNode);
                }

                foreach (var item in memberList)
                {
                    AddObject(memberPath, item, rows);
                }

                return;
            }

            var memberObj = value as IDictionary <string, object>;

            if (memberObj != null)
            {
                AddObject(memberPath, memberObj, rows);
                return;
            }

            // Value Row
            if (!key.StartsWith("@") && !memberPath.EndsWith("/#"))
            {
                memberPath += "/#";
            }

            // Multiple Value Row
            SharpValueType memberValueType;

            if (SharpValue.TryGetValueList(value, out memberValueType))
            {
                var memberValueListNode = _nodes.GetNode(memberPath);
                if (memberValueListNode == null)
                {
                    memberValueListNode = new SharpNode
                    {
                        Path        = memberPath,
                        Name        = SharpNode.GetNodeName(memberPath),
                        IsValueNode = true,
                        ValueType   = memberValueType,
                        NodeType    = SharpNodeType.Repeated
                    };
                    _nodes.Add(memberValueListNode);
                }

                foreach (var val in ((IEnumerable)value))
                {
                    rows.Add(new SharpValueRow(memberValueListNode, val));
                }

                return;
            }

            // Single Value Row
            var memberValue = new SharpValue(value);

            var memberNode = _nodes.GetNode(memberPath);

            if (memberNode == null)
            {
                memberNode = new SharpNode()
                {
                    Path        = memberPath,
                    Name        = SharpNode.GetNodeName(memberPath),
                    IsValueNode = true,
                    ValueType   = memberValue.Type
                };
                _nodes.Add(memberNode);
            }

            rows.Add(new SharpValueRow(memberNode, memberValue.Value));
        }
예제 #24
0
 public SharpValueRow(SharpNode node, object value)
 {
     RowType = SharpRowType.Value;
     Node    = node;
     Values.Add(value);
 }
예제 #25
0
        private List <SharpRow> ParseNextNode()
        {
            List <SharpRow> rows = new List <SharpRow>();

            switch (_reader.NodeType)
            {
            case System.Xml.XmlNodeType.Comment:
            {
                var lines = _reader.Value.Split('\n').Select(x => x.TrimEnd()).ToList();
                if (lines.Count > 0 && String.IsNullOrEmpty(lines.Last()))
                {
                    lines.RemoveAt(lines.Count - 1);
                }

                foreach (var line in lines)
                {
                    rows.Add(new SharpMetaCommentRow {
                            Value = line
                        });
                }

                break;
            }

            case System.Xml.XmlNodeType.XmlDeclaration:
                rows.Add(new SharpMetaParameterRow
                {
                    Key   = "XmlDeclaration",
                    Value = new SharpValue(_reader.Value)
                });
                break;

            case System.Xml.XmlNodeType.DocumentType:
                rows.Add(new SharpMetaParameterRow
                {
                    Key   = "DocumentType",
                    Value = new SharpValue(_reader.Value)
                });
                break;

            case System.Xml.XmlNodeType.ProcessingInstruction:
                rows.Add(new SharpMetaParameterRow
                {
                    Key   = _reader.Name,
                    Value = new SharpValue(_reader.Value)
                });
                break;

            case System.Xml.XmlNodeType.SignificantWhitespace:
            case System.Xml.XmlNodeType.Whitespace:
            case System.Xml.XmlNodeType.CDATA:
            case System.Xml.XmlNodeType.Text:
                if (_parseNode)
                {
                    _valueContent.Append(_reader.Value);
                    _hasContent = true;
                }
                break;

            case System.Xml.XmlNodeType.Element:
                if (_node == null)
                {
                    if (_fullPath.Count > 0)
                    {
                        _node = _nodes.GetOrCreateNode(_fullPath, false);
                        rows.Add(new SharpNodeRow(_node));
                    }
                }

                _fullPath.Add(_reader.Name);

                _isEmpty = _reader.IsEmptyElement;

                _node       = null;
                _hasContent = false;
                _parseNode  = true;
                _valueContent.Clear();
                _hasAttributes = false;

                if (_reader.HasAttributes)
                {
                    _hasAttributes = true;
                    _node          = _nodes.GetOrCreateNode(_fullPath, false);
                    rows.Add(new SharpNodeRow(_node));

                    for (int i = 0; i < _reader.AttributeCount; i++)
                    {
                        _reader.MoveToAttribute(i);

                        var attrPath = new List <string>(_fullPath);
                        attrPath.Add(string.Format("@{0}", _reader.Name));
                        var attrNode = _nodes.GetOrCreateNode(attrPath, false);
                        rows.Add(new SharpValueRow(attrNode, _reader.Value));
                    }
                }
                else if (_isEmpty)
                {
                    _node = _nodes.GetOrCreateNode(_fullPath, true);
                    rows.Add(new SharpValueRow(_node, null));
                    _hasContent = false;
                    _parseNode  = false;
                }

                if (_isEmpty)
                {
                    goto case System.Xml.XmlNodeType.EndElement;
                }

                break;

            case System.Xml.XmlNodeType.EndElement:
                if (_hasContent || _parseNode)
                {
                    var val = _valueContent.ToString();
                    if (_isEmpty || !_hasContent)
                    {
                        val = null;
                    }

                    if (_hasAttributes)
                    {
                        if (val != null)
                        {
                            var parent = _nodes.GetOrCreateNode(_fullPath, false);
                            _node = _nodes.GetOrCreateNode(_fullPath, true, parent);
                            rows.Add(new SharpValueRow(_node, val));
                        }
                    }
                    else
                    {
                        _node = _nodes.GetOrCreateNode(_fullPath, true);
                        rows.Add(new SharpValueRow(_node, val));
                    }

                    _hasContent = false;
                }
                _parseNode = false;
                if (_fullPath.Count > 0)
                {
                    _fullPath.RemoveAt(_fullPath.Count - 1);
                }

                break;
            }

            return(rows);
        }
예제 #26
0
        public static SharpNodeMap LoadHeaderLine(string line, char delimiter, SharpNodeCollection nodes, string path, Dictionary <string, string> aliases = null)
        {
            SharpNode rootNode = nodes.GetNode(path);

            if (rootNode == null)
            {
                rootNode = new SharpNode
                {
                    Path = path,
                    Name = SharpNode.GetNodeName(path),
                };
                nodes.Add(rootNode);
            }

            SharpNodeMap result = new SharpNodeMap();

            result.MapType = SharpMapType.Variable;

            var columns = line.Split(delimiter).Select(x => x.Trim().Trim('"')).ToList();

            foreach (var column in columns)
            {
                var colname = column;
                if (aliases != null)
                {
                    if (aliases.ContainsKey(colname))
                    {
                        colname = aliases[colname];
                    }
                }
                var nodePath = string.Format("{0}/{1}/#", path, colname);
                var colNode  = nodes.GetNode(nodePath);
                if (colNode == null)
                {
                    colNode = new SharpNode
                    {
                        Path        = nodePath,
                        Name        = colname,
                        IsValueNode = true,
                        IsLeafNode  = true
                    };
                    nodes.Add(colNode);
                }

                result.Columns.Add(new SharpNodeMapColumn(colNode)
                {
                    FieldName = column
                });
            }

            string mapPath = string.Join(",", result.Columns.Select(c => c.Node.Index));

            var mapNode = new SharpNodeMap
            {
                Path        = mapPath,
                IsValueNode = true,
                MapType     = SharpMapType.Variable,
                Delimiter   = delimiter,
            };

            mapNode.SetColumns(result.Columns);
            nodes.Add(mapNode);

            if (nodes.GetNode(mapPath) == null)
            {
                nodes.Add(mapNode);
            }

            return(mapNode);
        }
예제 #27
0
        public SharpNodeMap CreateColumnNodes(SharpNodeCollection nodes, string path, bool alwaysUpdateColumns = true)
        {
            SharpNode rootNode = nodes.GetNode(path);

            if (rootNode == null)
            {
                rootNode = new SharpNode
                {
                    Path = path,
                    Name = SharpNode.GetNodeName(path),
                };
                nodes.Add(rootNode);
            }

            using (var reader = new StreamReader(_source, _encoding))
            {
                int position = 0;
                while (!reader.EndOfStream)
                {
                    var line = reader.ReadLine();
                    if (line == null)
                    {
                        continue;
                    }

                    line = line.Trim();
                    if (string.IsNullOrEmpty(line))
                    {
                        continue;
                    }

                    var parts = line.Split(',').Select(x => x.Trim()).ToList();

                    string fieldName  = parts[0];
                    string columnName = fieldName;
                    if (_names.ContainsKey(columnName))
                    {
                        columnName = _names[columnName];
                    }

                    if (columnName == "EOR")
                    {
                        continue;
                    }

                    string columnPath = string.Format("{0}/{1}/#", rootNode.Path, columnName);
                    int    columnWidth;
                    int.TryParse(parts[1], out columnWidth);

                    var columnNode = nodes.GetNode(columnPath);

                    if (columnNode == null)
                    {
                        columnNode = new SharpNode
                        {
                            Path        = columnPath,
                            Name        = columnName,
                            IsValueNode = true,
                            ValueType   = _types.ContainsKey(columnName) ? _types[columnName] : SharpValueType.None,
                        };

                        nodes.Add(columnNode);
                    }

                    var column = new SharpNodeMapColumn(columnNode, columnWidth, position);
                    column.FieldName = fieldName;

                    if (_allowTrim.ContainsKey(columnName))
                    {
                        column.AllowTrim = _allowTrim[columnName];
                    }

                    if (_alignLeft.ContainsKey(columnName))
                    {
                        column.AlignLeft = _alignLeft[columnName];
                    }

                    if (_format.ContainsKey(columnName))
                    {
                        column.Format = _format[columnName];
                    }

                    if (_padding.ContainsKey(columnName))
                    {
                        column.Padding = _padding[columnName];
                    }

                    position += columnWidth;
                    _columns.Add(column);
                }
            }

            string mapPath = string.Join(",", _columns.Select(c => c.Node.Index));

            var mapNode = new SharpNodeMap
            {
                Path        = mapPath,
                IsValueNode = true
            };

            mapNode.SetColumns(_columns);
            mapNode.MapType = SharpMapType.Fixed;

            if (nodes.GetNode(mapPath) == null)
            {
                nodes.Add(mapNode);
            }
            else
            {
                mapNode.Parent = nodes.GetNode(mapPath).Parent;
            }
            return(mapNode);
        }
예제 #28
0
        public virtual IEnumerable <SharpRow> GetRows(SharpNode node = null)
        {
            var stack = new List <bool>();

            foreach (var row in _rows)
            {
                var nodeRow = row as SharpNodeRow;
                if (nodeRow != null)
                {
                    var top      = nodeRow;
                    var stackPos = 0;
                    stack.Add(false);

                    while (top != null)
                    {
                        bool processNode = true;

                        if (!stack[stackPos])
                        {
                            if (node == null || node == top.Node)
                            {
                                yield return(top);
                            }

                            // Short circuit any branches past the selected node or any branches that don't
                            // contain the selected node.
                            if (node != null && (node == top.Node || !top.Node.HasDescendant(node)))
                            {
                                processNode = false;
                            }
                        }

                        if (!stack[stackPos] && top.First != null && processNode)
                        {
                            stack[stackPos] = true;
                            stackPos++;
                            if (stackPos >= stack.Count)
                            {
                                stack.Add(false);
                            }
                            else
                            {
                                stack[stackPos] = false;
                            }
                            top = top.First;
                        }
                        else if (top.Next != null)
                        {
                            stack[stackPos] = false;
                            top             = top.Next;
                        }
                        else if (top == nodeRow)
                        {
                            top = null;
                        }
                        else
                        {
                            stackPos--;
                            top = top.Root;
                        }
                    }
                }
                else
                {
                    if (node == null)
                    {
                        yield return(row);
                    }
                }
            }
        }