/// <summary> /// Parses the specified text into a tree of <see cref="NodeInfo"/>. /// </summary> /// <param name="text">The text to parse.</param> /// <param name="predicate">If true, the <see cref="XElement"/> will not be loaded.</param> /// <param name="schemaRegistry">Stores the schema of each XML node.</param> /// <returns>The root <see cref="NodeInfo"/>.</returns> internal static NodeInfo Parse(string text, Func <XElement, bool> predicate, SchemaRegistry schemaRegistry) { return(new NodeInfo(XDocument.Parse(text, LoadOptions.SetLineInfo).Root, null, predicate, schemaRegistry)); }
/// <summary> /// Creates node groups based upon their schema from the specified node inforation. /// </summary> /// <param name="nodeInfo">The node information for the root node.</param> /// <param name="schemaRegistry">Stores the schemas of all created nodes.</param> /// <param name="count">The total number of nodes created.</param> /// <returns>Nodes grouped by their schema ID.</returns> internal static ImmutableDictionary <int, ImmutableArray <Node> > CreateGroups(NodeInfo nodeInfo, SchemaRegistry schemaRegistry, out int count) { var counter = new Counter(); var root = new Node(nodeInfo, null, counter, schemaRegistry); var nodes = new Node[count = counter.Current()]; var stack = new Stack <Node>(); stack.Push(root); while (stack.TryPop(out var node)) { nodes[node.Index] = node; foreach (var child in node.Children) { stack.Push(child); } } return(nodes.GroupBy(node => node.SchemaId).ToImmutableDictionary(grouping => grouping.Key, grouping => grouping.ToImmutableArray())); }
/// <summary> /// Creates a new instance of <see cref="NodeInfo"/>. /// </summary> /// <param name="element">The XML element.</param> /// <param name="parentSignature">The signature of the parent XML node.</param> /// <param name="predicate">If true, the <see cref="XElement"/> will not be loaded.</param> /// <param name="schemaRegistry">Stores the schema of the XML node.</param> private NodeInfo(XElement element, string parentSignature, Func <XElement, bool> predicate, SchemaRegistry schemaRegistry) { var name = element.Name.LocalName; var signature = parentSignature != null ? $"{parentSignature}.{name}" : name; var children = element.Elements().Where(predicate).Select(childElement => new NodeInfo(childElement, signature, predicate, schemaRegistry)); var properties = new Dictionary <string, Bigram>(); var text = (element.FirstNode as XText)?.Value; foreach (var attribute in element.Attributes()) { properties[attribute.Name.LocalName] = new Bigram(attribute.Value); } if (text != null) { properties["&text"] = new Bigram(text); } schemaRegistry.AddPropertyNames(signature, properties.Keys); Children = children; Element = element; Properties = properties; Signature = signature; }