public virtual void AppendNamespaces(XPathNamespace firstNew) { Debug.Assert(CheckDuplicates(firstNew), "List of namespases we are adding contains duplicates"); Debug.Assert(CheckDuplicates(topNamespace), "List of namespases of parent node contains duplicates"); Debug.Assert(firstNew != null, "Dont's call this unction if you don't have namespaces to add"); XPathNamespace lastNew = null; // Find the topmost unconflicting node in old list // and remove duplicates from the new list XPathNamespace unconflictOld = topNamespace; for (XPathNamespace tmpNew = firstNew; tmpNew != null; tmpNew = (XPathNamespace) tmpNew.next) { XPathNamespace confOld = FindByName(unconflictOld, tmpNew.Name); if (confOld != null) { // Even if confOld.Value == tmpNew.Value we have to replace this nsNode because new has different docIndex and be sorted differentely unconflictOld = (XPathNamespace) confOld.next; } // set parent to all of new ns and remember the last one as well; tmpNew.parent = this; lastNew = tmpNew; } XPathNamespace mirgedList = unconflictOld; // now mirgedList has only unconfliced part of parent namespace list // from interval (unconflictOld, topNamespace] attached to mirgedList clones of all unconflicting nodes for (XPathNamespace tmpOld = topNamespace; tmpOld != unconflictOld; tmpOld = (XPathNamespace) tmpOld.next) { if (FindByName(firstNew, tmpOld.Name) == null) { XPathNamespace clone = new XPathNamespace(tmpOld.Name, tmpOld.Value, tmpOld.DocumentIndex); clone.parent = tmpOld.parent; clone.next = mirgedList; mirgedList = clone; } else { // Just ignore it } } // now we can atach new nodes Debug.Assert(lastNew != null); lastNew.next = mirgedList; topNamespace = firstNew; Debug.Assert(CheckDuplicates(topNamespace), "List of namespases we just duilt contains duplicates"); }
public XPathEmptyElement( string prefix, string localName, string uri, int lineNumber, int linePosition, XPathNamespace topNamespace, int documentIndex ) : base( prefix, localName, uri, lineNumber, linePosition, topNamespace, documentIndex ) { }
public static bool CheckDuplicates(XPathNamespace list) { while(list != null) { if (FindByName((XPathNamespace) list.next, list.Name) != null) { return false; } list = (XPathNamespace) list.next; } return true; }
private static XPathNamespace FindByName(XPathNamespace list, string name) { Debug.Assert(name != null); while(list != null && list.Name != name) { list = (XPathNamespace) list.next; } return list; }
public XPathElement( string prefix, string localName, string uri, int lineNumber, int linePosition, XPathNamespace topNamespace , int documentIndex) : base( prefix, localName, uri, documentIndex ) { this.lineNumber = lineNumber; this.linePosition = linePosition; this.topNamespace = topNamespace; }
private void ReadAttributes( XPathElement parent, XmlReader reader ) { XPathNamespace last = null; while(reader.MoveToNextAttribute()) { documentIndex++; if ((object)reader.NamespaceURI == (object)xmlnsUri) { XPathNamespace tmp = new XPathNamespace(reader.Prefix == string.Empty ? string.Empty : reader.LocalName, reader.Value, documentIndex); tmp.next = last; last = tmp; } else { parent.AppendAttribute(new XPathAttribute(reader.Prefix, reader.LocalName, reader.NamespaceURI, reader.Value, documentIndex)); if (htElementIdMap != null) { Object attrname = htElementIdMap[new XmlQualifiedName(parent.Name, parent.Prefix)] ; if (attrname != null && new XmlQualifiedName(reader.Name, reader.Prefix).Equals(attrname)) { if (htElementIDAttrDecl[reader.Value] == null) { htElementIDAttrDecl.Add(reader.Value, parent); } } } } } if (last != null) { parent.AppendNamespaces(last); } }
public Processor.OutputResult RecordDone(RecordBuilder record) { Debug.Assert(record != null); BuilderInfo mainNode = record.MainNode; documentIndex++; mainNode.LocalName = doc.nt.Add(mainNode.LocalName); mainNode.NamespaceURI = doc.nt.Add(mainNode.NamespaceURI); switch(mainNode.NodeType) { case XmlNodeType.Element: { XPathElement e = mainNode.IsEmptyTag ? new XPathEmptyElement(mainNode.Prefix, mainNode.LocalName, mainNode.NamespaceURI, 0, 0, node.topNamespace, documentIndex) : new XPathElement( mainNode.Prefix, mainNode.LocalName, mainNode.NamespaceURI, 0, 0, node.topNamespace, documentIndex) ; node.AppendChild( e ); XPathNamespace last = null; for (int attrib = 0; attrib < record.AttributeCount; attrib ++) { documentIndex++; Debug.Assert(record.AttributeList[attrib] is BuilderInfo); BuilderInfo attrInfo = (BuilderInfo) record.AttributeList[attrib]; if (attrInfo.NamespaceURI == Keywords.s_XmlnsNamespace) { XPathNamespace tmp = new XPathNamespace(attrInfo.Prefix == string.Empty ? string.Empty : attrInfo.LocalName, attrInfo.Value, documentIndex); tmp.next = last; last = tmp; } else { e.AppendAttribute( new XPathAttribute( attrInfo.Prefix, attrInfo.LocalName, attrInfo.NamespaceURI, attrInfo.Value, documentIndex ) ); } } if (last != null) { e.AppendNamespaces(last); } if (!mainNode.IsEmptyTag) { node = e; } break; } case XmlNodeType.Text: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: node.AppendChild( new XPathText( mainNode.Value, 0, 0, documentIndex ) ); break; case XmlNodeType.ProcessingInstruction: node.AppendChild( new XPathProcessingInstruction( mainNode.LocalName, mainNode.Value, documentIndex ) ); break; case XmlNodeType.Comment: node.AppendChild( new XPathComment( mainNode.Value, documentIndex ) ); break; case XmlNodeType.Document: break; case XmlNodeType.EndElement: node = node.parent; break; default: Debug.Fail("Invalid NodeType on output: " + mainNode.NodeType.ToString()); break; } record.Reset(); return Processor.OutputResult.Continue; }