public void LoadElementAttributes(XmlElement xe) { if (xe == null) { Debug.Assert(false); return; } string str = xe.GetAttribute("MergeNodeMode"); if (!string.IsNullOrEmpty(str)) { switch (str) { // case "None": m_nm = XmNodeMode.None; break; case "Create": m_nm = XmNodeMode.Create; break; case "Open": m_nm = XmNodeMode.Open; break; case "OpenOrCreate": m_nm = XmNodeMode.OpenOrCreate; break; case "Remove": m_nm = XmNodeMode.Remove; break; default: Debug.Assert(false); break; } } str = xe.GetAttribute("MergeContentMode"); if (!string.IsNullOrEmpty(str)) { switch (str) { // case "None": m_cm = XmContentMode.None; break; case "Merge": m_cm = XmContentMode.Merge; break; case "Replace": m_cm = XmContentMode.Replace; break; default: Debug.Assert(false); break; } } str = xe.GetAttribute("MergeChildrenOtherMode"); if (!string.IsNullOrEmpty(str)) { switch (str) { case "None": m_com = XmChildrenOtherMode.None; break; case "Remove": m_com = XmChildrenOtherMode.Remove; break; default: Debug.Assert(false); break; } } str = xe.GetAttribute("MergeChildrenSortOrder"); if (!string.IsNullOrEmpty(str)) { switch (str) { // case "None": m_cso = XmChildrenSortOrder.None; break; case "Other": m_cso = XmChildrenSortOrder.Other; break; case "This": m_cso = XmChildrenSortOrder.This; break; default: Debug.Assert(false); break; } } }
internal static XmlElement MergeElements(XmlElement xeBase, XmlElement xeOverride, string strXPath, XmlElement xeBaseParent, XmContext ctx) { if (xeOverride == null) { throw new ArgumentNullException("xeOverride"); } if (strXPath == null) { throw new ArgumentNullException("strXPath"); } if (ctx == null) { throw new ArgumentNullException("ctx"); } string strName = xeOverride.Name; Debug.Assert((xeBase == null) || (xeBase.Name == strName)); Debug.Assert((strXPath == strName) || strXPath.EndsWith("/" + strName)); Debug.Assert((xeBase == null) || (xeBaseParent == null) || object.ReferenceEquals(xeBase.ParentNode, xeBaseParent)); XmNodeOptions o = GetNodeOptions(xeOverride, strXPath, ctx); bool bContinue = false; switch (o.NodeMode) { case XmNodeMode.None: break; case XmNodeMode.Create: if ((xeBase == null) && (xeBaseParent != null)) { xeBase = ctx.BaseDocument.CreateElement(strName); xeBaseParent.AppendChild(xeBase); bContinue = true; } break; case XmNodeMode.Open: if (xeBase != null) { bContinue = true; } break; case XmNodeMode.OpenOrCreate: if (xeBase != null) { bContinue = true; } else if (xeBaseParent != null) { xeBase = ctx.BaseDocument.CreateElement(strName); xeBaseParent.AppendChild(xeBase); bContinue = true; } break; case XmNodeMode.Remove: if (xeBase != null) { if (xeBaseParent != null) { xeBaseParent.RemoveChild(xeBase); xeBase = null; // Return value, indicate removal } else { // Cannot remove element; clear it instead xeBase.InnerXml = string.Empty; } } break; default: Debug.Assert(false); break; } if (!bContinue) { return(xeBase); } if (xeBase == null) { Debug.Assert(false); return(null); } XmContentMode cm = o.ContentMode; if ((cm == XmContentMode.Merge) && !HasChildElement(xeBase) && !HasChildElement(xeOverride)) { cm = XmContentMode.Replace; } XmElementCollection xcBase = null, xcOverride = null; if (cm == XmContentMode.Merge) { xcBase = XmElementCollection.FromChildNodes(xeBase, strXPath, ctx); xcOverride = XmElementCollection.FromChildNodes(xeOverride, strXPath, ctx); if (o.ChildrenOtherMode == XmChildrenOtherMode.Remove) { List <string> lRemove = new List <string>(); foreach (KeyValuePair <string, XmlElement> kvpBaseC in xcBase) { if (xcOverride[kvpBaseC.Key] == null) { xeBase.RemoveChild(kvpBaseC.Value); lRemove.Add(kvpBaseC.Key); } } // Do not simply rebuild xcBase, because indices in // node keys would change xcBase = xcBase.Except(lRemove); } } switch (cm) { case XmContentMode.None: Debug.Assert(false); break; // Currently unused case XmContentMode.Merge: foreach (KeyValuePair <string, XmlElement> kvpOverrideC in xcOverride) { string strKeyC = kvpOverrideC.Key; XmlElement xeBaseC = xcBase[strKeyC]; XmlElement xeOverrideC = kvpOverrideC.Value; string strXPathC = strXPath + "/" + xeOverrideC.Name; XmlElement xeBaseCNew = MergeElements(xeBaseC, xeOverrideC, strXPathC, xeBase, ctx); if (!object.ReferenceEquals(xeBaseCNew, xeBaseC)) { Debug.Assert((xeBaseCNew == null) || (xeBaseC == null)); if (xeBaseCNew == null) { xcBase.Remove(strKeyC); } else { xcBase.Add(strKeyC, xeBaseCNew); } } } break; case XmContentMode.Replace: xeBase.InnerXml = SafeInnerXml(xeOverride); break; default: Debug.Assert(false); break; } if ((cm == XmContentMode.Merge) && (o.ChildrenSortOrder == XmChildrenSortOrder.This)) { xcBase.SortBy(xcOverride); xcBase.ReorderElementsOf(xeBase); } return(xeBase); }