// 分支版本。不适合外部直接调用。 // 从指定位置向上(祖先),所有元素的属性都是展开状态,这可以直接利用 // 我们自己的DOM对象体系来搜集名字空间信息。 // 收集一个元素节点以外(上方)的名字空间信息。 // 包含element在内 // parameters: // element 基准元素 // return: // 返回名字空间信息集合 public static NamespaceItemCollection GatherOuterNamespacesByNativeDom( ElementItem element) { NamespaceItemCollection nsColl = new NamespaceItemCollection(); ElementItem current = (ElementItem)element; while (true) { if (current == null) { break; } if (current.m_attrsExpand == ExpandStyle.Collapse) { /* * // 为了枚举本层属性,不得不展开属性数组对象,但是暂时没有作收缩回的功能 * current.GetControl().ExpandChild(current, * ExpandStyle.Expand, * current.m_childrenExpand, * true); * Debug.Assert( current.m_attrsExpand == ExpandStyle.Expand, * "展开后m_attrsExpand应当为true"); */ Debug.Assert(false, "调用本函数的人,应当确保从要求位置向上祖先路径中,每个元素的属性集合都是处于展开状态。"); } foreach (AttrItem attr in current.attrs) { if (attr.IsNamespace == false) { continue; } nsColl.Add(attr.LocalName, attr.GetValue(), true); // 只要prefix重就不加入 } current = (ElementItem)current.parent; } return(nsColl); }
// 假定nsColl中的信息即将还原为xml的属性字符串,插入element节点的属性集合中, // 本函数为确保不会发生属性重名的错误,而特意对nsColl去重 public static void RemoveAttributeDup(ElementItem element, ref NamespaceItemCollection nsColl) { if (nsColl.Count == 0) { return; } // 对基准元素的属性进行一次去重操作 if (element.attrs != null) { for (int i = 0; i < nsColl.Count; i++) { NamespaceItem item = (NamespaceItem)nsColl[i]; string strAttrString = item.AttrName; bool bOccurNamespaceAttr = false; foreach (AttrItem attr in element.attrs) { if (attr.IsNamespace == false) { continue; } bOccurNamespaceAttr = true; if (attr.Name == strAttrString) { nsColl.RemoveAt(i); i--; break; } } if (bOccurNamespaceAttr == false) { break; // 说明element.attrs集合中,全部是普通类型的属性,没有名字空间型的属性,那样就意味着不用去重了 } } } }
// 假定nsColl中的信息即将还原为xml的属性字符串,插入element节点的属性集合中, // 本函数为确保不会发生属性重名的错误,而特意对nsColl去重 public static void RemoveAttributeDup(ElementItem element, ref NamespaceItemCollection nsColl) { if (nsColl.Count == 0) return; // 对基准元素的属性进行一次去重操作 if (element.attrs != null) { for(int i=0; i<nsColl.Count; i++) { NamespaceItem item = (NamespaceItem)nsColl[i]; string strAttrString = item.AttrName; bool bOccurNamespaceAttr = false; foreach(AttrItem attr in element.attrs) { if (attr.IsNamespace == false) continue; bOccurNamespaceAttr = true; if (attr.Name == strAttrString) { nsColl.RemoveAt(i); i--; break; } } if (bOccurNamespaceAttr == false) break; // 说明element.attrs集合中,全部是普通类型的属性,没有名字空间型的属性,那样就意味着不用去重了 } } }
// 分支版本。不适合外部直接调用。 // 从指定位置向上(祖先),所有元素的属性都是展开状态,这可以直接利用 // 我们自己的DOM对象体系来搜集名字空间信息。 // 收集一个元素节点以外(上方)的名字空间信息。 // 包含element在内 // parameters: // element 基准元素 // return: // 返回名字空间信息集合 public static NamespaceItemCollection GatherOuterNamespacesByNativeDom( ElementItem element) { NamespaceItemCollection nsColl = new NamespaceItemCollection(); ElementItem current = (ElementItem)element; while(true) { if (current == null) break; if (current.m_attrsExpand == ExpandStyle.Collapse) { /* // 为了枚举本层属性,不得不展开属性数组对象,但是暂时没有作收缩回的功能 current.GetControl().ExpandChild(current, ExpandStyle.Expand, current.m_childrenExpand, true); Debug.Assert( current.m_attrsExpand == ExpandStyle.Expand, "展开后m_attrsExpand应当为true"); */ Debug.Assert(false, "调用本函数的人,应当确保从要求位置向上祖先路径中,每个元素的属性集合都是处于展开状态。"); } foreach(AttrItem attr in current.attrs) { if (attr.IsNamespace == false) continue; nsColl.Add(attr.LocalName, attr.GetValue(), true); // 只要prefix重就不加入 } current = (ElementItem)current.parent; } return nsColl; }
// 分支版本。不适合外部直接调用。 // 从指定位置向上(祖先),有一个以上元素的属性是收缩状态,这样就没法 // 利用我们自己的DOM对象体系来搜集名字空间信息,只能模拟一个XML局部字符串来借用 // .net DOM来帮助搜集名字空间信息 public static NamespaceItemCollection GatherOuterNamespacesByDotNetDom( ElementItem element) { string strXml = ""; NamespaceItemCollection nsColl = new NamespaceItemCollection(); ElementItem current = (ElementItem)element; while(true) { if (current == null || current is VirtualRootItem) break; strXml = "<" + current.Name + current.GetAttrsXml() + ">" + strXml + "</" + current.Name + ">"; current = (ElementItem)current.parent; } if (strXml == "") return nsColl; XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { throw (new Exception("GatherOuterNamespacesByDotNetDom()加载模拟xml代码出错: " + ex.Message)); } // 先确定起点 XmlNode currentNode = dom.DocumentElement; while(true) { if (currentNode.ChildNodes.Count == 0) break; currentNode = currentNode.ChildNodes[0]; } Debug.Assert(currentNode != null, ""); // 开始搜集信息 while(true) { if (currentNode == null) break; foreach(XmlAttribute attr in currentNode.Attributes) { if (attr.Prefix != "xmlns" && attr.LocalName != "xmlns") continue; if (attr.LocalName == "xmlns") nsColl.Add("", attr.Value, true); // 只要prefix重就不加入 else nsColl.Add(attr.LocalName, attr.Value, true); // 只要prefix重就不加入 } currentNode = currentNode.ParentNode; if (currentNode is XmlDocument) // 这样就算到根以上了 break; } return nsColl; }
// 优化本层的名字空间 public void YouHuaOneLevel() { NamespaceItemCollection namespaceItems = new NamespaceItemCollection(); ItemList parentNamespaces = null; if (this.parent != null) { parentNamespaces = ((ElementItem)this.parent).NamespaceList; } if (this.attrs != null && parentNamespaces != null) { ArrayList aNamespaceAttr = new ArrayList(); foreach(AttrItem attr in this.attrs) { if (attr.IsNamespace == true) { //namespaceItems.Add(attr.Name,attr.Value); foreach(Item parentNamespace in parentNamespaces) { if (parentNamespace.Name == attr.Name && parentNamespace.Value != attr.Value) { break; } if (parentNamespace.Name == attr.Name && parentNamespace.Value == attr.Value) { aNamespaceAttr.Add(attr); } } } } foreach(AttrItem namespaceAttr in aNamespaceAttr) { this.RemoveAttrInternal(namespaceAttr,true); // 要改成Internal } } if (this.children != null) { foreach(Item item in this.children) { if (item is ElementItem) { ElementItem element = (ElementItem)item; element.YouHuaOneLevel(); } } } }
// 分支版本。不适合外部直接调用。 // 从指定位置向上(祖先),有一个以上元素的属性是收缩状态,这样就没法 // 利用我们自己的DOM对象体系来搜集名字空间信息,只能模拟一个XML局部字符串来借用 // .net DOM来帮助搜集名字空间信息 public static NamespaceItemCollection GatherOuterNamespacesByDotNetDom( ElementItem element) { string strXml = ""; NamespaceItemCollection nsColl = new NamespaceItemCollection(); ElementItem current = (ElementItem)element; while (true) { if (current == null || current is VirtualRootItem) { break; } strXml = "<" + current.Name + current.GetAttrsXml() + ">" + strXml + "</" + current.Name + ">"; current = (ElementItem)current.parent; } if (strXml == "") { return(nsColl); } XmlDocument dom = new XmlDocument(); try { dom.LoadXml(strXml); } catch (Exception ex) { throw (new Exception("GatherOuterNamespacesByDotNetDom()加载模拟xml代码出错: " + ex.Message)); } // 先确定起点 XmlNode currentNode = dom.DocumentElement; while (true) { if (currentNode.ChildNodes.Count == 0) { break; } currentNode = currentNode.ChildNodes[0]; } Debug.Assert(currentNode != null, ""); // 开始搜集信息 while (true) { if (currentNode == null) { break; } foreach (XmlAttribute attr in currentNode.Attributes) { if (attr.Prefix != "xmlns" && attr.LocalName != "xmlns") { continue; } if (attr.LocalName == "xmlns") { nsColl.Add("", attr.Value, true); // 只要prefix重就不加入 } else { nsColl.Add(attr.LocalName, attr.Value, true); // 只要prefix重就不加入 } } currentNode = currentNode.ParentNode; if (currentNode is XmlDocument) // 这样就算到根以上了 { break; } } return(nsColl); }