示例#1
0
        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;
                }
            }
        }
示例#2
0
        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);
        }