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 '&nbsp;'
                            doc.ReplaceValue("\u00A0");
                            break;

                        case ProcessingMode.RemoveEmpty:
                            doc.Remove();
                            break;
                        }
                    }
                }
            }
        }
Example #2
0
        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 '&nbsp;'
                            doc.ReplaceValue("\u00A0");
                            break;
                        case ProcessingMode.RemoveEmpty:
                            doc.Remove();
                            break;
                        }
                    }
                }
            }
        }