private void Enforce(XDoc doc, bool removeIllegalElements, bool isRoot) { if (doc.IsEmpty) { return; } // process child elements List <XDoc> list = doc.Elements.ToList(); foreach (XDoc child in list) { Enforce(child, removeIllegalElements, false); } // skip processing of root element if (!isRoot) { // process element Element elementRule; if (!Elements.TryGetValue(doc.Name, out elementRule)) { // element is not valid; determine what to do with it if (removeIllegalElements) { // replace it with its contents doc.ReplaceWithNodes(doc); } else { StringBuilder attributes = new StringBuilder(); foreach (XmlAttribute attribute in doc.AsXmlNode.Attributes) { attributes.Append(" "); attributes.Append(attribute.OuterXml); } // replace it with text version of itself if (doc.AsXmlNode.ChildNodes.Count == 0) { doc.AddBefore("<" + doc.Name + attributes.ToString() + "/>"); doc.Remove(); } else { doc.AddBefore("<" + doc.Name + attributes.ToString() + ">"); doc.AddAfter("</" + doc.Name + ">"); doc.ReplaceWithNodes(doc); } } return; } else if (doc.Name != elementRule.Name) { // element has an obsolete name, substitute it doc.Rename(elementRule.Name); } // process attributes List <XmlAttribute> attributeList = new List <XmlAttribute>(); foreach (XmlAttribute attribute in doc.AsXmlNode.Attributes) { attributeList.Add(attribute); } // remove unsupported attributes if (!elementRule.Attributes.ContainsKey("*")) { foreach (XmlAttribute attribute in attributeList) { Attribute attributeRule; elementRule.Attributes.TryGetValue(attribute.Name, out attributeRule); if ((attributeRule == null) && (_wildcardElement != null)) { _wildcardElement.Attributes.TryGetValue(attribute.Name, out attributeRule); } if ((attributeRule == null) || ((attributeRule.LegalValues.Length > 0) && (Array.BinarySearch <string>(attributeRule.LegalValues, attribute.Value) < 0))) { doc.RemoveAttr(attribute.Name); } } } // add default attributes foreach (Attribute attributeRule in elementRule.Attributes.Values) { if ((attributeRule.DefaultValue != null) && (doc.AsXmlNode.Attributes[attributeRule.Name] == null)) { doc.Attr(attributeRule.Name, attributeRule.DefaultValue); } } // process empty element if (list.Count == 0) { // check if the contents are empty string contents = doc.Contents; if ((contents.Trim().Length == 0) && (contents.IndexOf('\u00A0') < 0)) { switch (elementRule.Mode) { case ProcessingMode.PadEmpty: // add ' ' doc.ReplaceValue("\u00A0"); break; case ProcessingMode.RemoveEmpty: doc.Remove(); break; } } } } }
private void Enforce(XDoc doc, bool removeIllegalElements, bool isRoot) { if(doc.IsEmpty) { return; } // process child elements List<XDoc> list = doc.Elements.ToList(); foreach(XDoc child in list) { Enforce(child, removeIllegalElements, false); } // skip processing of root element if(!isRoot) { // process element Element elementRule; if(!Elements.TryGetValue(doc.Name, out elementRule)) { // element is not valid; determine what to do with it if(removeIllegalElements) { // replace it with its contents doc.ReplaceWithNodes(doc); } else { StringBuilder attributes = new StringBuilder(); foreach(XmlAttribute attribute in doc.AsXmlNode.Attributes) { attributes.Append(" "); attributes.Append(attribute.OuterXml); } // replace it with text version of itself if(doc.AsXmlNode.ChildNodes.Count == 0) { doc.AddBefore("<" + doc.Name + attributes.ToString() + "/>"); doc.Remove(); } else { doc.AddBefore("<" + doc.Name + attributes.ToString() + ">"); doc.AddAfter("</" + doc.Name + ">"); doc.ReplaceWithNodes(doc); } } return; } else if(doc.Name != elementRule.Name) { // element has an obsolete name, substitute it doc.Rename(elementRule.Name); } // process attributes List<XmlAttribute> attributeList = new List<XmlAttribute>(); foreach(XmlAttribute attribute in doc.AsXmlNode.Attributes) { attributeList.Add(attribute); } // remove unsupported attributes if(!elementRule.Attributes.ContainsKey("*")) { foreach(XmlAttribute attribute in attributeList) { Attribute attributeRule; elementRule.Attributes.TryGetValue(attribute.Name, out attributeRule); if((attributeRule == null) && (_wildcardElement != null)) { _wildcardElement.Attributes.TryGetValue(attribute.Name, out attributeRule); } if((attributeRule == null) || ((attributeRule.LegalValues.Length > 0) && (Array.BinarySearch<string>(attributeRule.LegalValues, attribute.Value) < 0))) { doc.RemoveAttr(attribute.Name); } } } // add default attributes foreach(Attribute attributeRule in elementRule.Attributes.Values) { if((attributeRule.DefaultValue != null) && (doc.AsXmlNode.Attributes[attributeRule.Name] == null)) { doc.Attr(attributeRule.Name, attributeRule.DefaultValue); } } // process empty element if(list.Count == 0) { // check if the contents are empty string contents = doc.Contents; if((contents.Trim().Length == 0) && (contents.IndexOf('\u00A0') < 0)) { switch(elementRule.Mode) { case ProcessingMode.PadEmpty: // add ' ' doc.ReplaceValue("\u00A0"); break; case ProcessingMode.RemoveEmpty: doc.Remove(); break; } } } } }