/// <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; }
// 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); }
// 把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); }
// 把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); }
// 把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); }
// 复制构造函数 /// <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; }
// 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); }
// 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); }
// 追加 // 对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; }
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"); }
// 对一批互相没有树重叠关系的对象进行筛选 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]; } } }
// 移走一个对象 // 返回包含移走的对象的集合 /// <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()); }
// 用一个元素构造出数组 /// <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); }
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); }
// 将机内格式的字符串设置到字段 // 最后一个字符可以是 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); } }
// 观察 node 是否和集合中的任何一个节点有重叠关系 static bool isCross(MarcNode node, MarcNodeList list) { foreach (MarcNode current in list) { if (isCross(current, node) == true) { return(true); } } return(false); }
/// <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()); }
/// <summary> /// 获得根节点 /// </summary> /// <returns>根节点</returns> public MarcNode getRootNode() { MarcNode node = this; while (node.Parent != null) { node = node.Parent; } Debug.Assert(node.Parent == null, ""); return(node); }
// 从数组中移走全部对象 // 注意,本函数并不修改所移走的对象的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); }
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); }
// 在目标集合中每个元素的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++; } }
/// <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++; } }
// 在目标集合中每个元素的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++; } }
// /// <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()); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
// 观察两个 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); }
// 把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; }
/// <summary> /// 初始化一个 MarcNode 对象 /// </summary> public MarcNode() { this.Parent = null; this.ChildNodes.owner = this; }
// 把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; }
/// <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; }
/// <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; }
/// <summary> /// 初始化一个 NaviItem 对象 /// </summary> /// <param name="node">要关联的 MarcNode 节点</param> /// <param name="type">要初始化的对象的类型</param> public NaviItem(MarcNode node, NaviItemType type) { this.MarcNode = node; this.Type = type; }
/// <summary> /// 初始化一个 MarcNode对象,并设置好其 Parent 成员 /// </summary> /// <param name="parent">上级 MarcNode 对象</param> public MarcNode(MarcNode parent) { this.Parent = parent; this.ChildNodes.owner = this; }
// 复制构造函数 public NavigatorState(NavigatorState NavState) { this.CurItem = new NaviItem(NavState.CurItem); // 复制。位置参数都需要复制,因为复制的对象里面的这些状态以后可能被修改 this.DocRoot = NavState.DocRoot; // 引用。因为都是针对的同一个文档,文档本身并不需要复制 // this.VirtualRoot = NavState.VirtualRoot; }
/// <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); }
// 追加一个元素 // 返回增补对象后的当前集合 /// <summary> /// 在当前集合末尾添加一个元素 /// </summary> /// <param name="node">要添加的元素</param> /// <returns>添加元素后的当前集合</returns> public MarcNodeList add(MarcNode node) { this.m_list.Add(node); return(this); }
// 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; }
// 把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; }
// 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; }
// 检查加入,不去摘除 node 原来的关系,也不自动修改 node.Parent internal void baseAdd(MarcNode node) { base.add(node); }