public void RewriteNestedSiblingParents() { var xml = @" <root> <parent1/> <parent2/> <parent3/> <parent4/> <parent5/> </root> "; var document = new XmlDocument(); document.LoadXml(xml); var rootPair = new XmlPair(null, null); var parent1 = (XmlElement)document.GetElementsByTagName("parent1")[0]; var parent5 = (XmlElement)document.GetElementsByTagName("parent5")[0]; var pair1 = new XmlPair(rootPair, parent1) { End = parent5 }; rootPair.Children.Add(pair1); var parent2 = (XmlElement)document.GetElementsByTagName("parent2")[0]; var parent4 = (XmlElement)document.GetElementsByTagName("parent4")[0]; var pair2 = new XmlPair(rootPair, parent2) { End = parent4 }; pair1.Children.Add(pair2); rootPair.Rewrite(v => v.Document.CreateElement("allors")); var expected = @" <root> <allors> <allors> <parent3/> </allors> </allors> </root>"; var diff = DiffBuilder.Compare(Input.FromDocument(document)).WithTest(Input.FromString(expected)).Build(); Assert.False(diff.HasDifferences(), diff.ToString()); }
private void Prepare(XmlElement parent, ref XmlPair parentPair, Stack <XmlPair> stack, Dictionary <XmlElement, Binding> bindingByOriginalXmlElement) { foreach (XmlNode node in parent.ChildNodes) { if (node is XmlElement element) { if (element.LocalName.Equals("placeholder") && element.NamespaceURI.Contains("opendocument:xmlns:text")) { var text = element.InnerText.Trim(); // Bindings var match = BindingRegex.Match(text); if (match.Success) { bindingByOriginalXmlElement[element] = new Binding(match.Groups[1].ToString()); } // Instructions (for/if) if (ForRegex.Match(text).Success || IfRegex.Match(text).Success) { var childNode = new XmlPair(parentPair, element); stack.Push(childNode); parentPair.Children.Add(childNode); parentPair = childNode; } // Instructions (end) if (EndRegex.Match(text).Success) { var childNode = stack.Pop(); childNode.End = element; parentPair = childNode.Parent; } } if (element.LocalName.Equals("frame") && element.NamespaceURI.Contains("opendocument:xmlns:drawing")) { var drawNs = element.GetNamespaceOfPrefix("draw"); var name = element.GetAttribute("name", drawNs).Trim(); if (name.StartsWith("$")) { var value = this.LeftDelimiter + name.Substring(1) + this.RightDelimiter; element.SetAttribute("name", drawNs, value); } } this.Prepare(element, ref parentPair, stack, bindingByOriginalXmlElement); } } }
public OpenDocumentTemplateContent(byte[] content, char leftDelimiter, char rightDelimiter) { this.LeftDelimiter = leftDelimiter; this.RightDelimiter = rightDelimiter; this.bindingByXmlElement = new Dictionary <XmlElement, Binding>(); this.statementByXmlElement = new Dictionary <XmlElement, Statement>(); this.template = new XmlDocument(); using (var input = new MemoryStream(content)) { this.template.Load(input); } var root = new XmlPair(null, null); var stack = new Stack <XmlPair>(); var documentElement = this.template.DocumentElement; var walker = root; var bindingByOriginalXmlElement = new Dictionary <XmlElement, Binding>(); this.Prepare(documentElement, ref walker, stack, bindingByOriginalXmlElement); var forCounter = 0; XmlElement Factory(XmlPair pair) { var text = pair.Begin.InnerText.Trim(); var match = ForRegex.Match(text); if (match.Success) { var element = pair.Document.CreateElement("for"); var statement = new For(++forCounter, match.Groups[1].ToString()); this.statementByXmlElement.Add(element, statement); return(element); } if ((match = IfRegex.Match(text)).Success) { var element = pair.Document.CreateElement("if"); var statement = new If(match.Groups[1].ToString()); this.statementByXmlElement.Add(element, statement); return(element); } throw new Exception("Unknown statement: " + pair.Begin.InnerText); } foreach (var pair in bindingByOriginalXmlElement) { var xmlElement = pair.Key; var binding = pair.Value; var bindingElement = this.template.CreateElement("binding"); var parent = xmlElement.ParentNode; parent.InsertBefore(bindingElement, xmlElement); parent.RemoveChild(xmlElement); this.bindingByXmlElement.Add(bindingElement, binding); } root.Rewrite(Factory); }