Exemple #1
0
 /// <summary>
 /// 向当前集合中添加一个节点元素,按节点名字顺序决定加入的位置
 /// </summary>
 /// <param name="node">要加入的节点</param>
 /// <param name="style">如何加入</param>
 /// <param name="comparer">用于比较大小的接口</param>
 public override void insertSequence(MarcNode node,
                                     InsertSequenceStyle style     = InsertSequenceStyle.PreferHead,
                                     IComparer <MarcNode> comparer = null)
 {
     base.insertSequence(node, style, comparer);
     node.Parent = owner;
 }
Exemple #2
0
 // this 插入到 target 儿子的末尾
 /// <summary>
 /// 将当前节点追加到指定(目标)节点的子节点末尾
 /// </summary>
 /// <param name="target">目标节点</param>
 /// <returns>当前节点</returns>
 public MarcNode appendTo(MarcNode target)
 {
     this.detach();
     target.ChildNodes.add(this);
     this.Parent = target;
     return(this);
 }
Exemple #3
0
 // 把source插入到this的下级开头位置。返回this
 /// <summary>
 /// 将指定的(源)节点插入到当前节点的子节点开头位置
 /// </summary>
 /// <param name="source">源节点</param>
 /// <returns>当前节点</returns>
 public MarcNode prepend(MarcNode source)
 {
     source.detach();
     this.ChildNodes.insert(0, source);
     source.Parent = this;
     return(this);
 }
Exemple #4
0
        // 把source插入到this的后面。返回this
        /// <summary>
        /// 将指定节点插入到当前节点的后面兄弟位置
        /// </summary>
        /// <param name="source">要插入的节点</param>
        /// <returns>当前节点</returns>
        public MarcNode after(MarcNode source)
        {
            MarcNode parent = this.Parent;

            // 自己是根节点,无法具有兄弟
            if (parent == null)
            {
                throw new Exception("无法在根节点同级插入新节点");
            }

            int index = parent.ChildNodes.indexOf(this);

            if (index == -1)
            {
                throw new Exception("parent的ChildNodes中居然没有找到自己");
            }

            // 进行类型检查,同级只能插入相同类型的元素
            if (this.NodeType != source.NodeType)
            {
                throw new Exception("无法在节点同级插入不同类型的新节点。this.NodeTYpe=" + this.NodeType.ToString() + ", source.NodeType=" + source.NodeType.ToString());
            }

            source.detach();
            parent.ChildNodes.insert(index + 1, source);
            source.Parent = this.Parent;
            return(this);
        }
Exemple #5
0
 // 把source插入到this的下级末尾位置。返回this
 /// <summary>
 /// 将指定节点追加到当前节点的子节点尾部
 /// </summary>
 /// <param name="source">要追加的节点</param>
 /// <returns>当前节点</returns>
 public MarcNode append(MarcNode source)
 {
     source.detach();
     this.ChildNodes.add(source);
     source.Parent = this;
     return(this);
 }
Exemple #6
0
 // 复制构造函数
 /// <summary>
 /// 初始化一个 NaviItem 对象
 /// </summary>
 /// <param name="other">复制时参考的对象</param>
 public NaviItem(NaviItem other)
 {
     this.Type = other.Type;
     this.MarcNode = other.MarcNode;
     this.AttrName = other.AttrName;
     this.Text = other.Text;
 }
Exemple #7
0
 // 复制构造函数
 /// <summary>
 /// 初始化一个 NaviItem 对象
 /// </summary>
 /// <param name="other">复制时参考的对象</param>
 public NaviItem(NaviItem other)
 {
     this.Type     = other.Type;
     this.MarcNode = other.MarcNode;
     this.AttrName = other.AttrName;
     this.Text     = other.Text;
 }
Exemple #8
0
        // return true if the XPathNavigator is successful moving to the previous sibling node; otherwise , false if there is no previous sibling node or if the XPathNavigator is currently positioned on an attribute node.
        /// <summary>
        /// 移动到当前节点的前一个兄弟节点
        /// </summary>
        /// <returns>如果移动成功,返回 true;否则返回 false。当返回 false 时,表示当前位置没有发生变动。</returns>
        public override bool MoveToPrevious()
        {
            ////Debug.WriteLine("MoveToPrevious");
            ////Debug.WriteLine("*** Current " + this.m_navigatorState.Dump());
            Debug.Assert(this.m_navigatorState.CurItem != null, "");

            // 已在虚根上
            if (this.m_navigatorState.CurItem.Type == NaviItemType.VirtualRoot)
            {
                return(false);
            }

            // Attribute 节点返回 false。Text节点因为不会有兄弟,所以也返回 false
            if (this.m_navigatorState.CurItem.Type != NaviItemType.Element)
            {
                return(false);
            }

            MarcNode parent = this.m_navigatorState.CurItem.MarcNode.Parent;

            if (parent == null)
            {
                return(false);
            }

            int nIndex = parent.ChildNodes.indexOf(this.m_navigatorState.CurItem.MarcNode);

            if (nIndex - 1 < 0)
            {
                return(false);   // 已经到兄弟开头
            }
            this.m_navigatorState.CurItem.MarcNode = parent.ChildNodes[nIndex - 1];
            ////Debug.WriteLine("*** Changed " + this.m_navigatorState.Dump());
            return(true);
        }
Exemple #9
0
 // this 插入到 target 的儿子的第一个
 /// <summary>
 /// 将当前节点插入到指定的(目标)节点的子节点的开头
 /// </summary>
 /// <param name="target">目标节点</param>
 /// <returns>当前节点</returns>
 public MarcNode prependTo(MarcNode target)
 {
     this.detach();
     target.ChildNodes.insert(0, this);
     this.Parent = target;
     return(this);
 }
Exemple #10
0
        // 追加
        // 对node先要摘除
        /// <summary>
        /// 在当前集合末尾追加一个节点元素
        /// </summary>
        /// <param name="node">要追加的节点</param>
        public new void add(MarcNode node)
        {
            node.detach();
            base.add(node);

            Debug.Assert(owner != null, "");
            node.Parent = owner;
        }
Exemple #11
0
 public NavigatorState(NaviItem item)
 {
     CurItem = item;
     //VirtualRoot = new NaviItem(item.MarcNode.Root, NaviItemType.VirtualRoot);
     //Debug.Assert(VirtualRoot != null, "VirtualRoot不能为null");
     DocRoot = item.MarcNode.Root;
     Debug.Assert(DocRoot != null, "DocRoot不能为null");
 }
Exemple #12
0
        // 对一批互相没有树重叠关系的对象进行筛选
        static MarcNodeList simpleSelect(MarcNodeList source,
                                         string strXPath,
                                         int nMaxCount = -1)
        {
            // 准备一个模拟的记录节点
            // MarcRecord record = new MarcRecord();
            MarcNode temp_root = new MarcNode();

            temp_root.Name = "temp";

            // 保存下集合中所有的Parent指针
            List <MarcNode> parents = new List <MarcNode>();

            foreach (MarcNode node in source)
            {
                // 保存指针
                parents.Add(node.Parent);

                // 建立父子关系,但原来位置的ChidNodes并不摘除
                temp_root.ChildNodes.baseAdd(node);
                node.Parent = temp_root;
                // Debug.Assert(node.Parent == temp_root, "");
            }
            Debug.Assert(parents.Count == source.count, "");

            try
            {
                MarcNodeList results = new MarcNodeList();

                MarcNavigator nav = new MarcNavigator(temp_root);  // 出发点在模拟的记录节点上

                XPathNodeIterator ni = nav.Select(strXPath);
                while (ni.MoveNext() && (nMaxCount == -1 || results.count < nMaxCount))
                {
                    NaviItem item = ((MarcNavigator)ni.Current).Item;
                    if (item.Type != NaviItemType.Element)
                    {
                        throw new Exception("xpath '" + strXPath + "' 命中了非元素类型的节点,这是不允许的");
                        continue;
                    }
                    if (results.indexOf(item.MarcNode) == -1)   // 不重复的才加入
                    {
                        results.add(item.MarcNode);
                    }
                }
                return(results);
            }
            finally
            {
                // 恢复原先的 Parent 指针
                Debug.Assert(parents.Count == source.count, "");
                for (int i = 0; i < source.count; i++)
                {
                    source[i].Parent = parents[i];
                }
            }
        }
Exemple #13
0
        // 移走一个对象
        // 返回包含移走的对象的集合
        /// <summary>
        /// 从当前集合中移走指定的元素
        /// </summary>
        /// <param name="node">要移走的元素</param>
        /// <returns>被移走的一个元素(所构成的新集合)</returns>
        public MarcNodeList remove(MarcNode node)
        {
            bool bRet = this.m_list.Remove(node);   // TODO: 查阅一下返回值的含义

            if (bRet == true)
            {
                return(new MarcNodeList(node));
            }
            return(new MarcNodeList());
        }
Exemple #14
0
 // 用一个元素构造出数组
 /// <summary>
 /// 初始化一个 MarcNodeList 对象,并填入一个 MarcNode 对象
 /// </summary>
 /// <param name="node">要填入的 MarcNode 对象。若本参数为 null,则初始化一个空的集合对象</param>
 public MarcNodeList(MarcNode node)
 {
     // 如果使用null,可以构造出一个空的集合。这是为了方便使用,尽量不要报错
     // 例如 new MarcNodeList(node.FirstChild) 如果 FirstChild 为空可以构造出一个空的集合,如果后面利用这个集合继续操作也无害
     if (node == null)
     {
         return;
     }
     this.add(node);
 }
Exemple #15
0
        public virtual void insertSequenceReverse(MarcNode node,
                                                  InsertSequenceStyle style     = InsertSequenceStyle.PreferHead,
                                                  IComparer <MarcNode> comparer = null)
        {
            if (comparer == null)
            {
                comparer = new MarcNodeComparer();
            }

            // 寻找插入位置
            List <int> values     = new List <int>(); // 累积每个比较结果数字
            int        nInsertPos = -1;

            for (int i = this.count - 1; i >= 0; i--)
            {
                MarcNode current = this[i];

                int nBigThanCurrent = 0;   // 相当于node和当前对象相减

                nBigThanCurrent = comparer.Compare(node, current) * -1;
                if (nBigThanCurrent < 0)
                {
                    nInsertPos = i + 1;
                    break;
                }
                if (nBigThanCurrent == 0)
                {
                    if ((style & InsertSequenceStyle.PreferTail) != 0)
                    {
                        nInsertPos = i;
                        break;
                    }
                }

                // 刚刚遇到过相等的一段,但在当前位置结束了相等 (或者开始变大,或者开始变小)
                if (nBigThanCurrent != 0 && values.Count > 0 && values[values.Count - 1] == 0)
                {
                    if ((style & InsertSequenceStyle.PreferHead) != 0)
                    {
                        nInsertPos = i;
                        break;
                    }
                }

                values.Add(nBigThanCurrent);
            }

            if (nInsertPos == -1)
            {
                this.m_list.Insert(0, node);
                return;
            }

            this.m_list.Insert(nInsertPos, node);
        }
Exemple #16
0
        // 将机内格式的字符串设置到字段
        // 最后一个字符可以是 30 (表示字段结束),也可以没有这个字符
        void setFieldText(string strText)
        {
            // 去掉末尾的 30 字符
            if (strText != null && strText.Length >= 1)
            {
                if (strText[strText.Length - 1] == (char)30)
                {
                    strText = strText.Substring(0, strText.Length - 1);
                }
            }

            if (string.IsNullOrEmpty(strText) == true)
            {
                throw new Exception("字段 Text 不能设置为空");
            }

            if (strText.Length < 3)
            {
                throw new Exception("字段 Text 不能设置为小于 3 字符");
            }

            string strFieldName = strText.Substring(0, 3);

            strText = strText.Substring(3); // 剩余部分

            this.m_strName = strFieldName;
            if (MarcNode.isControlFieldName(strFieldName) == true)
            {
                throw new Exception("MARC 外围字段的字段名不能使用控制字段名 '" + strFieldName + "'");
            }
            else
            {
                // 普通字段

                // 剩下的内容为空
                if (string.IsNullOrEmpty(strText) == true)
                {
                    this.Indicator = DefaultIndicator;
                    return;
                }

                // 还剩下一个字符
                if (strText.Length < 2)
                {
                    Debug.Assert(strText.Length == 1, "");
                    this.Indicator = strText + new string(MarcQuery.DefaultChar, 1);
                    return;
                }

                // 剩下两个字符以上
                this.m_strIndicator = strText.Substring(0, 2);
                this.Content        = strText.Substring(2);
            }
        }
Exemple #17
0
 // 观察 node 是否和集合中的任何一个节点有重叠关系
 static bool isCross(MarcNode node, MarcNodeList list)
 {
     foreach (MarcNode current in list)
     {
         if (isCross(current, node) == true)
         {
             return(true);
         }
     }
     return(false);
 }
Exemple #18
0
        /// <summary>
        /// 输出当前对象的全部子对象的调试用字符串
        /// </summary>
        /// <returns>表示内容的字符串</returns>
        public virtual string dumpChildren()
        {
            StringBuilder strResult = new StringBuilder(4096);

            for (int i = 0; i < this.ChildNodes.count; i++)
            {
                MarcNode child = this.ChildNodes[i];
                strResult.Append(child.dump());
            }

            return(strResult.ToString());
        }
Exemple #19
0
        /// <summary>
        /// 获得根节点
        /// </summary>
        /// <returns>根节点</returns>
        public MarcNode getRootNode()
        {
            MarcNode node = this;

            while (node.Parent != null)
            {
                node = node.Parent;
            }

            Debug.Assert(node.Parent == null, "");
            return(node);
        }
Exemple #20
0
        // 从数组中移走全部对象
        // 注意,本函数并不修改所移走的对象的Parent成员。也就是说移走的对象并未完全被detach
        // 返回移出的nodes
        /// <summary>
        /// 从当前集合中移走全部元素。注意,本函数并不修改所移走的元素的 Parent 成员。也就是说移走的元素并未完全被摘除
        /// </summary>
        /// <returns>已经被移走的全部元素</returns>
        public MarcNodeList remove()
        {
            MarcNodeList results = new MarcNodeList();

            for (int i = 0; i < this.count; i++)
            {
                MarcNode node = this[i];
                MarcNode temp = node.remove();
                if (temp != null)
                {
                    results.add(node);
                }
            }

            return(results);
        }
Exemple #21
0
        public override bool MoveToFirst()
        {
            //StreamUtil.WriteText("I:\\debug.txt",this.Name + "--MoveToFirst() \r\n");
            Debug.Assert(this.m_navigatorState.CurItem != null, "");

            if (this.m_navigatorState.CurItem.Type == NaviItemType.VirtualRoot)
            {
                return(false);
            }
            if (this.m_navigatorState.CurItem == this.m_navigatorState.DocRoot)
            {
                return(false);
            }

            if (this.m_navigatorState.CurItem.Type != NaviItemType.Element)
            {
                MoveToElement();
            }
#if NO
            if (this.m_navigatorState.CurItem.Type == NaviItemType.Text)
            {
                return(false);
            }

            // ???
            if (this.m_navigatorState.CurItem.Type == NaviItemType.Attribute)
            {
                Debug.Assert(false, "");
                string strAttrName = this.m_navigatorState.CurItem.FirstAttrName;
                if (strAttrName == null)
                {
                    return(false);
                }
                this.m_navigatorState.CurItem.AttrName = strAttrName;
                return(true);
            }
#endif

            MarcNode parent = this.m_navigatorState.CurItem.MarcNode.Parent;
            if (parent == null)
            {
                return(true);
            }

            this.m_navigatorState.CurItem.MarcNode = parent.ChildNodes[0];
            return(true);
        }
Exemple #22
0
        // 在目标集合中每个元素的DOM位置后面(同级)插入源集合内的元素
        // 注1: 如果目标集合为空,则本函数不作任何操作。这样可以防止元素被摘除但没有插入到任何位置
        // 注2:将 源 插入到 目标 元素的DOM位置后面。如果源头元素在DOM树上,则先摘除它然后插入到新位置,不是复制。
        // 注3: 如果目标集合中包含多于一个元素,则分为多轮插入。第二轮以后插入的对象,是源集合中的对象复制出来的新对象
        /// <summary>
        /// 在目标集合中每个元素的 DOM 位置后面(同级)插入源集合内的元素
        /// </summary>
        /// <param name="source_nodes">源集合</param>
        /// <param name="target_nodes">目标集合</param>
        public static void insertAfter(
            MarcNodeList source_nodes,
            MarcNodeList target_nodes)
        {
            if (source_nodes.count == 0)
            {
                return;
            }
            if (target_nodes.count == 0)
            {
                return;
            }

            // record.SelectNodes("field[@name='690']")[0].ChildNodes.after(SUBFLD + "x第一个" + SUBFLD + "z第二个");
            if (target_nodes is ChildNodeList)
            {
                // 数组框架复制,但其中的元素不是复制而是引用
                MarcNodeList temp = new MarcNodeList();
                temp.add(target_nodes);
                target_nodes = temp;
            }

            // 先(从原有DOM位置)摘除当前集合内的全部元素
            source_nodes.detach();
            int i = 0;

            foreach (MarcNode target_node in target_nodes)
            {
                MarcNode target = target_node;
                foreach (MarcNode source_node in source_nodes)
                {
                    MarcNode source = source_node;
                    if (i > 0)  // 第一轮以后,源对象每个都要复制后插入目标位置
                    {
                        source = source.clone();
                        target.after(source);
                    }
                    else
                    {
                        target.after(source);
                    }
                    target = source;   // 插入后参考位置要顺延
                }
                i++;
            }
        }
Exemple #23
0
        /// <summary>
        /// 在目标集合中每个元素的 DOM 位置前面(同级)插入源集合内的元素
        /// </summary>
        /// <param name="source_nodes">源集合</param>
        /// <param name="target_nodes">目标集合</param>
        public static void insertBefore(
            MarcNodeList source_nodes,
            MarcNodeList target_nodes)
        {
            if (source_nodes.count == 0)
            {
                return;
            }
            if (target_nodes.count == 0)
            {
                return;
            }

            if (target_nodes is ChildNodeList)
            {
                // 数组框架复制,但其中的元素不是复制而是引用
                MarcNodeList temp = new MarcNodeList();
                temp.add(target_nodes);
                target_nodes = temp;
            }

            // 先(从原有DOM位置)摘除当前集合内的全部元素
            source_nodes.detach();
            int i = 0;

            foreach (MarcNode target_node in target_nodes)
            {
                MarcNode target = target_node;
                foreach (MarcNode source_node in source_nodes)
                {
                    MarcNode source = source_node;
                    if (i > 0)  // 第一轮以后,源对象每个都要复制后插入目标位置
                    {
                        source = source.clone();
                        target.before(source);
                    }
                    else
                    {
                        target.before(source);
                    }
                    target = source;   // 插入后参考位置要顺延
                }
                i++;
            }
        }
Exemple #24
0
        // 在目标集合中每个元素的DOM位置 下级开头 插入源集合内的元素
        /// <summary>
        /// 在目标集合中每个元素的 DOM 位置下级开头插入源集合内的元素
        /// </summary>
        /// <param name="source_nodes">源集合</param>
        /// <param name="target_nodes">目标集合</param>
        public static void prepend(
            MarcNodeList source_nodes,
            MarcNodeList target_nodes)
        {
            if (source_nodes.count == 0)
            {
                return;
            }
            if (target_nodes.count == 0)
            {
                return;
            }

            // 防范目标集合被动态修改后发生foreach报错
            if (target_nodes is ChildNodeList)
            {
                // 数组框架复制,但其中的元素不是复制而是引用
                MarcNodeList temp = new MarcNodeList();
                temp.add(target_nodes);
                target_nodes = temp;
            }

            // 先(从原有DOM位置)摘除当前集合内的全部元素
            source_nodes.detach();
            int i = 0;

            foreach (MarcNode target_node in target_nodes)
            {
                foreach (MarcNode source_node in source_nodes)
                {
                    MarcNode source = source_node;
                    if (i > 0)  // 第一轮以后,源对象每个都要复制后插入目标位置
                    {
                        source = source.clone();
                        target_node.prepend(source);
                    }
                    else
                    {
                        target_node.prepend(source);
                    }
                }
                i++;
            }
        }
Exemple #25
0
        //
        /// <summary>
        /// 获得表示当前对象的位置的路径。用于比较节点之间的位置关系
        /// </summary>
        /// <returns>路径字符串</returns>
        public string getPath()
        {
            MarcNode parent = this.Parent;

            if (parent == null)
            {
                return("0");
            }
            int index = parent.ChildNodes.indexOf(this);

            if (index == -1)
            {
                throw new Exception("在父节点的 ChildNodes 中没有找到自己");
            }

            string strParentPath = this.Parent.getPath();

            return(strParentPath + "/" + index.ToString());
        }
Exemple #26
0
        /// <summary>
        /// 初始化一个 MarcNavigator 类的实例。
        /// </summary>
        /// <param name="node">出发点的 MarcNode 对象</param>
        public MarcNavigator(MarcNode node)
        {
#if NO
            //StreamUtil.WriteText("I:\\debug.txt","进到 构造函数XmlEditorNavigator(editor)里\r\n");

            Debug.Assert(node != null, "item不能为null");

            this.m_navigatorState             = new NavigatorState();
            this.m_navigatorState.CurItem     = new NaviItem(node, NaviItemType.Element);
            this.m_navigatorState.DocRoot     = new NaviItem(node.Root, NaviItemType.Element);
            this.m_navigatorState.VirtualRoot = this.m_navigatorState.DocRoot;

            this.m_nametable = new NameTable();
            this.m_nametable.Add(String.Empty);
#endif
            Debug.Assert(node != null, "node不能为null");
            NaviItem item = new NaviItem(node, NaviItemType.Element);
            Initial(item);
        }
Exemple #27
0
		/// <summary>
		/// 初始化一个 MarcNavigator 类的实例。
		/// </summary>
		/// <param name="node">出发点的 MarcNode 对象</param>
		public MarcNavigator(MarcNode node)
		{
#if NO
			//StreamUtil.WriteText("I:\\debug.txt","进到 构造函数XmlEditorNavigator(editor)里\r\n");

			Debug.Assert(node != null,"item不能为null");

            this.m_navigatorState = new NavigatorState();
            this.m_navigatorState.CurItem = new NaviItem(node, NaviItemType.Element);
            this.m_navigatorState.DocRoot = new NaviItem(node.Root, NaviItemType.Element);
            this.m_navigatorState.VirtualRoot = this.m_navigatorState.DocRoot;

            this.m_nametable = new NameTable();
            this.m_nametable.Add(String.Empty);
#endif
            Debug.Assert(node != null, "node不能为null");
            NaviItem item = new NaviItem(node, NaviItemType.Element);
            Initial(item);
		}
Exemple #28
0
        /// <summary>
        /// 将当前节点从父节点摘除。但依然保留对当前节点对下级的拥有关系
        /// </summary>
        /// <returns>已经被摘除的当前节点</returns>
        public MarcNode detach()
        {
            MarcNode parent = this.Parent;

            if (parent == null)
            {
                return(this); // 自己是根节点,或者先前已经被摘除
            }
            int index = parent.ChildNodes.indexOf(this);

            if (index == -1)
            {
                throw new Exception("parent的ChildNodes中居然没有找到自己");
                return(this);
            }

            parent.ChildNodes.removeAt(index);
            this.Parent = null;
            return(this);
        }
Exemple #29
0
        /// <summary>
        /// 移动到当前节点的下一个兄弟节点
        /// </summary>
        /// <returns>如果移动成功,返回 true;否则返回 false。当返回 false 时,表示当前位置没有发生变动。</returns>
        public override bool MoveToNext()
        {
            ////Debug.WriteLine("MoveToNext");
            ////Debug.WriteLine("*** Current " + this.m_navigatorState.Dump());
            Debug.Assert(this.m_navigatorState.CurItem != null, "");

            // 已在虚根上
            if (this.m_navigatorState.CurItem.Type == NaviItemType.VirtualRoot)
            {
                return(false);
            }

            // Attribute 节点返回 false。Text节点因为不会有兄弟,所以也返回 false
            if (this.m_navigatorState.CurItem.Type != NaviItemType.Element)
            {
                return(false);
            }

            MarcNode parent = this.m_navigatorState.CurItem.MarcNode.Parent;

            if (parent == null)
            {
                return(false);
            }

            int nIndex = parent.ChildNodes.indexOf(this.m_navigatorState.CurItem.MarcNode);

            if (nIndex == -1)
            {
                throw new Exception("MarcNode在parent的ChildNodes中没有找到自己");
            }

            if (nIndex >= parent.ChildNodes.count - 1)
            {
                return(false);   // 已经到兄弟末尾
            }
            this.m_navigatorState.CurItem.MarcNode = parent.ChildNodes[nIndex + 1];
            ////Debug.WriteLine("*** Changed " + this.m_navigatorState.Dump());
            return(true);
        }
Exemple #30
0
        // 观察两个 MarcNode 之间是否有重叠关系
        static bool isCross(MarcNode node1, MarcNode node2)
        {
            MarcNode current = node1;

            while (current != null)
            {
                if (current == node2)
                {
                    return(true);
                }
                current = current.Parent;
            }
            current = node2;
            while (current != null)
            {
                if (current == node1)
                {
                    return(true);
                }
                current = current.Parent;
            }

            return(false);
        }
Exemple #31
0
 // 把source插入到this的下级末尾位置。返回this
 /// <summary>
 /// 将指定节点追加到当前节点的子节点尾部
 /// </summary>
 /// <param name="source">要追加的节点</param>
 /// <returns>当前节点</returns>
 public MarcNode append(MarcNode source)
 {
     source.detach();
     this.ChildNodes.add(source);
     source.Parent = this;
     return this;
 }
Exemple #32
0
 /// <summary>
 /// 初始化一个 MarcNode 对象
 /// </summary>
 public MarcNode()
 {
     this.Parent = null;
     this.ChildNodes.owner = this;
 }
Exemple #33
0
        // 把source插入到this的后面。返回this
        /// <summary>
        /// 将指定节点插入到当前节点的后面兄弟位置
        /// </summary>
        /// <param name="source">要插入的节点</param>
        /// <returns>当前节点</returns>
        public MarcNode after(MarcNode source)
        {
            MarcNode parent = this.Parent;
            // 自己是根节点,无法具有兄弟
            if (parent == null)
                throw new Exception("无法在根节点同级插入新节点");

            int index = parent.ChildNodes.indexOf(this);
            if (index == -1)
            {
                throw new Exception("parent的ChildNodes中居然没有找到自己");
            }

            // 进行类型检查,同级只能插入相同类型的元素
            if (this.NodeType != source.NodeType)
                throw new Exception("无法在节点同级插入不同类型的新节点。this.NodeTYpe="+this.NodeType.ToString()+", source.NodeType="+source.NodeType.ToString());

            source.detach();
            parent.ChildNodes.insert(index+1, source);
            source.Parent = this.Parent;
            return this;
        }
Exemple #34
0
        /// <summary>
        /// 将当前节点从父节点摘除。但依然保留对当前节点对下级的拥有关系
        /// </summary>
        /// <returns>已经被摘除的当前节点</returns>
        public MarcNode detach()
        {
            MarcNode parent = this.Parent;
            if (parent == null)
                return this; // 自己是根节点,或者先前已经被摘除
            int index = parent.ChildNodes.indexOf(this);
            if (index == -1)
            {
                throw new Exception("parent的ChildNodes中居然没有找到自己");
                return this;
            }

            parent.ChildNodes.removeAt(index);
            this.Parent = null;
            return this;
        }
Exemple #35
0
     /// <summary>
     /// 向当前集合中添加一个节点元素,按节点名字顺序决定加入的位置
     /// </summary>
     /// <param name="node">要加入的节点</param>
     /// <param name="style">如何加入</param>
     /// <param name="comparer">用于比较大小的接口</param>
     public override void insertSequence(MarcNode node,
 InsertSequenceStyle style = InsertSequenceStyle.PreferHead,
 IComparer<MarcNode> comparer = null)
     {
         base.insertSequence(node, style, comparer);
         node.Parent = owner;
     }
Exemple #36
0
 /// <summary>
 /// 初始化一个 NaviItem 对象
 /// </summary>
 /// <param name="node">要关联的 MarcNode 节点</param>
 /// <param name="type">要初始化的对象的类型</param>
 public NaviItem(MarcNode node, NaviItemType type)
 {
     this.MarcNode = node;
     this.Type = type;
 }
Exemple #37
0
 /// <summary>
 /// 初始化一个 MarcNode对象,并设置好其 Parent 成员
 /// </summary>
 /// <param name="parent">上级 MarcNode 对象</param>
 public MarcNode(MarcNode parent)
 {
     this.Parent = parent;
     this.ChildNodes.owner = this;
 }
Exemple #38
0
            // 复制构造函数
			public NavigatorState(NavigatorState NavState)
			{
				this.CurItem = new NaviItem(NavState.CurItem);  // 复制。位置参数都需要复制,因为复制的对象里面的这些状态以后可能被修改
				this.DocRoot = NavState.DocRoot;    // 引用。因为都是针对的同一个文档,文档本身并不需要复制
				// this.VirtualRoot = NavState.VirtualRoot;
			}
Exemple #39
0
 /// <summary>
 /// 在当前集合指定的下标位置插入一个元素
 /// </summary>
 /// <param name="index">插入点的下标</param>
 /// <param name="node">要插入的元素</param>
 /// <returns>插入了新元素后的当前集合</returns>
 public MarcNodeList insert(int index, MarcNode node)
 {
     this.m_list.Insert(index, node);
     return(this);
 }
Exemple #40
0
 // 追加一个元素
 // 返回增补对象后的当前集合
 /// <summary>
 /// 在当前集合末尾添加一个元素
 /// </summary>
 /// <param name="node">要添加的元素</param>
 /// <returns>添加元素后的当前集合</returns>
 public MarcNodeList add(MarcNode node)
 {
     this.m_list.Add(node);
     return(this);
 }
Exemple #41
0
            public NavigatorState(NaviItem item)
			{
				CurItem = item;
				//VirtualRoot = new NaviItem(item.MarcNode.Root, NaviItemType.VirtualRoot);
				//Debug.Assert(VirtualRoot != null, "VirtualRoot不能为null");
                DocRoot = item.MarcNode.Root;
				Debug.Assert(DocRoot != null, "DocRoot不能为null");
			}
Exemple #42
0
 // this 插入到 target 儿子的末尾
 /// <summary>
 /// 将当前节点追加到指定(目标)节点的子节点末尾
 /// </summary>
 /// <param name="target">目标节点</param>
 /// <returns>当前节点</returns>
 public MarcNode appendTo(MarcNode target)
 {
     this.detach();
     target.ChildNodes.add(this);
     this.Parent = target;
     return this;
 }
Exemple #43
0
 // 把source插入到this的下级开头位置。返回this
 /// <summary>
 /// 将指定的(源)节点插入到当前节点的子节点开头位置
 /// </summary>
 /// <param name="source">源节点</param>
 /// <returns>当前节点</returns>
 public MarcNode prepend(MarcNode source)
 {
     source.detach();
     this.ChildNodes.insert(0, source);
     source.Parent = this;
     return this;
 }
Exemple #44
0
        // 追加
        // 对node先要摘除
        /// <summary>
        /// 在当前集合末尾追加一个节点元素
        /// </summary>
        /// <param name="node">要追加的节点</param>
        public new void add(MarcNode node)
        {
            node.detach();
            base.add(node);

            Debug.Assert(owner != null, "");
            node.Parent = owner;
        }
Exemple #45
0
 // this 插入到 target 的儿子的第一个
 /// <summary>
 /// 将当前节点插入到指定的(目标)节点的子节点的开头
 /// </summary>
 /// <param name="target">目标节点</param>
 /// <returns>当前节点</returns>
 public MarcNode prependTo(MarcNode target)
 {
     this.detach();
     target.ChildNodes.insert(0, this);
     this.Parent = target;
     return this;
 }
Exemple #46
0
 // 检查加入,不去摘除 node 原来的关系,也不自动修改 node.Parent
 internal void baseAdd(MarcNode node)
 {
     base.add(node);
 }