protected override void Parse() { document = XDocument.Load(templateFile.FullName, LoadOptions.PreserveWhitespace); rootPart = new XMLTemplatePart(document.Root); rootPart.Parse(); Root = rootPart; }
private void ParseElement(XElement element) { // Scan for comments // For each token comment, add it to token collection // For each start of template, next node is the template // - There should only be one between start and end of a template // Then also check the attributes for token replacements bool atleastOneReplacement = false; List <XAttribute> attributes = new List <XAttribute>(); foreach (XAttribute attribute in element.Attributes()) { if (TryParseAttributeValueForTokens(attribute.Name, attribute.Value, out XmlAttributeTemplateToken toReplace)) { attributes.Add(toReplace); atleastOneReplacement = true; } else { attributes.Add(attribute); } } if (atleastOneReplacement) { element.ReplaceAttributes(attributes); } List <Action> replacementActions = new List <Action>(); string templateStartKey = null; bool seenTemplateBody = false; foreach (XNode node in element.Nodes()) { if (node is XComment comment) { switch (GetTokenType(comment, out string tokenKey)) { case TokenType.ReplacementToken: XmlCommentTemplateToken xmlCommentTemplateToken = new XmlCommentTemplateToken(comment.Value); AddReplacementToken(tokenKey, xmlCommentTemplateToken); replacementActions.Add(() => comment.ReplaceWith(xmlCommentTemplateToken)); break; case TokenType.TemplateStart: templateStartKey = tokenKey; seenTemplateBody = false; break; case TokenType.TemplateEnd: if (templateStartKey == null) { throw new InvalidOperationException($"We have template end '{tokenKey}' without equivalent start."); } else if (!Equals(templateStartKey, tokenKey)) { throw new InvalidOperationException($"We have template end '{tokenKey}' but the template start was different '{templateStartKey}'."); } else if (!seenTemplateBody) { throw new InvalidOperationException($"We have template '{tokenKey}' without a body."); } else { templateStartKey = null; seenTemplateBody = false; } break; } } else if (node is XElement childElement) { if (templateStartKey != null) { if (seenTemplateBody) { throw new InvalidOperationException($"Template '{templateStartKey}' can only have one body node."); } else { XMLTemplatePart templatePart = new XMLTemplatePart(childElement); templatePart.Parse(); templates.Add(templateStartKey, templatePart); replacementActions.Add(() => childElement.ReplaceWith(templatePart)); seenTemplateBody = true; } } else { ParseElement(childElement); } } } replacementActions.ForEach(t => t()); }