Bloom.Book.BookData.GatherDataItemsFromXElement C# (CSharp) Method

GatherDataItemsFromXElement() private method

walk through the sourceDom, collecting up values from elements that have data-book or data-collection or data-book-attributes attributes.
private GatherDataItemsFromXElement ( DataSet data, XmlNode sourceElement, string>.HashSet itemsToDelete = null ) : void
data DataSet
sourceElement System.Xml.XmlNode
itemsToDelete string>.HashSet
return void
        private void GatherDataItemsFromXElement(DataSet data,
			XmlNode sourceElement, // can be the whole sourceDom or just a page
			HashSet<Tuple<string, string>> itemsToDelete = null)
        {
            string elementName = "*";
            try
            {
                string query = String.Format(".//{0}[(@data-book or @data-library or @data-collection or @data-book-attributes) and not(contains(@class,'bloom-writeOnly'))]", elementName);

                XmlNodeList nodesOfInterest = sourceElement.SafeSelectNodes(query);

                foreach (XmlElement node in nodesOfInterest)
                {
                    bool isCollectionValue = false;

                    string key = node.GetAttribute("data-book").Trim();
                    if (key == String.Empty)
                    {
                        key = node.GetAttribute("data-book-attributes").Trim();
                        if (key != String.Empty)
                        {
                            GatherAttributes(data, node, key);
                            continue;
                        }
                        key = node.GetAttribute("data-collection").Trim();
                        if (key == String.Empty)
                        {
                            key = node.GetAttribute("data-library").Trim(); //the old (pre-version 1) name of collections was 'library'
                        }
                        isCollectionValue = true;
                    }

                    string value;
                    if (HtmlDom.IsImgOrSomethingWithBackgroundImage(node))
                    {
                        value = HtmlDom.GetImageElementUrl(new ElementProxy(node)).UrlEncoded;
                        KeysOfVariablesThatAreUrlEncoded.Add(key);
                    }
                    else
                    {
                        var node1 = node.CloneNode(true); // so we can remove labels without modifying node
                        // Datadiv content should be node content without labels. The labels are not really part
                        // of the content we want to replicate, they are just information for the user, and
                        // specific to one context. Also, including them causes them to get repeated in each location;
                        // SetInnerXmlPreservingLabel() assumes data set content does not include label elements.
                        var labels = node1.SafeSelectNodes(".//label").Cast<XmlElement>().ToList();
                        foreach (var label in labels)
                            label.ParentNode.RemoveChild(label);
                        value = node1.InnerXml.Trim(); //may contain formatting
                        if(KeysOfVariablesThatAreUrlEncoded.Contains(key))
                        {
                            value = UrlPathString.CreateFromHtmlXmlEncodedString(value).UrlEncoded;
                        }
                    }

                    string lang = node.GetOptionalStringAttribute("lang", "*");
                    if (lang == "") //the above doesn't stop a "" from getting through
                        lang = "*";
                    if (lang == "{V}")
                        lang = _collectionSettings.Language1Iso639Code;
                    if(lang == "{N1}")
                        lang = _collectionSettings.Language2Iso639Code;
                    if(lang == "{N2}")
                        lang = _collectionSettings.Language3Iso639Code;

                    if (string.IsNullOrEmpty(value))
                    {
                        // This is a value we may want to delete
                        if (itemsToDelete != null)
                            itemsToDelete.Add(Tuple.Create(key, lang));
                    }
                    else if (!value.StartsWith("{"))
                        //ignore placeholder stuff like "{Book Title}"; that's not a value we want to collect
                    {
                        if ((elementName.ToLowerInvariant() == "textarea" || elementName.ToLowerInvariant() == "input" ||
                             node.GetOptionalStringAttribute("contenteditable", "false") == "true") &&
                            (lang == "V" || lang == "N1" || lang == "N2"))
                        {
                            throw new ApplicationException(
                                "Editable element (e.g. TextArea) should not have placeholder @lang attributes (V,N1,N2)\r\n\r\n" +
                                node.OuterXml);
                        }

                        //if we don't have a value for this variable and this language, add it
                        if (!data.TextVariables.ContainsKey(key))
                        {
                            var t = new MultiTextBase();
                            t.SetAlternative(lang, value);
                            data.TextVariables.Add(key, new NamedMutliLingualValue(t, isCollectionValue));
                        }
                        else if (!data.TextVariables[key].TextAlternatives.ContainsAlternative(lang))
                        {
                            MultiTextBase t = data.TextVariables[key].TextAlternatives;
                            t.SetAlternative(lang, value);
                        }
                    }

                    if (KeysOfVariablesThatAreUrlEncoded.Contains(key))
                    {
                        Debug.Assert(!value.Contains("&amp;"), "In memory, all image urls should be encoded such that & is just &.");
                    }

                }
            }
            catch (Exception error)
            {
                throw new ApplicationException(
                    "Error in GatherDataItemsFromDom(," + elementName + "). RawDom was:\r\n" + sourceElement.OuterXml,
                    error);
            }
        }