private void Clear () { currentToken = new XmlTokenInfo (this); cursorToken = currentToken; currentAttribute = -1; currentAttributeValue = -1; attributeCount = 0; readState = ReadState.Initial; depth = 0; elementDepth = 0; depthUp = false; popScope = allowMultipleRoot = false; elementNameStackPos = 0; isStandalone = false; returnEntityReference = false; entityReferenceName = String.Empty; #if USE_NAME_BUFFER nameLength = 0; nameCapacity = initialNameCapacity; #endif useProceedingLineInfo = false; currentState = XmlNodeType.None; readCharsInProgress = false; }
// The leading '<' has already been consumed. private void ReadStartTag () { if (currentState == XmlNodeType.EndElement) throw NotWFError ("Multiple document element was detected."); currentState = XmlNodeType.Element; nsmgr.PushScope (); currentLinkedNodeLineNumber = line; currentLinkedNodeLinePosition = column; string prefix, localName; string name = ReadName (out prefix, out localName); if (currentState == XmlNodeType.EndElement) throw NotWFError ("document has terminated, cannot open new element"); bool isEmptyElement = false; ClearAttributes (); SkipWhitespace (); if (XmlChar.IsFirstNameChar (PeekChar ())) ReadAttributes (false); cursorToken = this.currentToken; // fill namespaces for (int i = 0; i < attributeCount; i++) attributeTokens [i].FillXmlns (); for (int i = 0; i < attributeCount; i++) attributeTokens [i].FillNamespace (); // quick name check if (namespaces) for (int i = 0; i < attributeCount; i++) if (attributeTokens [i].Prefix == "xmlns" && attributeTokens [i].Value == String.Empty) throw NotWFError ("Empty namespace URI cannot be mapped to non-empty prefix."); for (int i = 0; i < attributeCount; i++) { for (int j = i + 1; j < attributeCount; j++) if (Object.ReferenceEquals (attributeTokens [i].Name, attributeTokens [j].Name) || (Object.ReferenceEquals (attributeTokens [i].LocalName, attributeTokens [j].LocalName) && Object.ReferenceEquals (attributeTokens [i].NamespaceURI, attributeTokens [j].NamespaceURI))) throw NotWFError ("Attribute name and qualified name must be identical."); } if (PeekChar () == '/') { Advance ('/'); isEmptyElement = true; popScope = true; } else { depthUp = true; PushElementName (name, localName, prefix); } parserContext.PushScope (); Expect ('>'); SetProperties ( XmlNodeType.Element, // nodeType name, // name prefix, // prefix localName, // name isEmptyElement, // isEmptyElement null, // value false // clearAttributes ); if (prefix.Length > 0) currentToken.NamespaceURI = LookupNamespace (prefix, true); else if (namespaces) currentToken.NamespaceURI = nsmgr.DefaultNamespace; if (namespaces) { if (NamespaceURI == null) throw NotWFError (String.Format ("'{0}' is undeclared namespace.", Prefix)); try { for (int i = 0; i < attributeCount; i++) { MoveToAttribute (i); if (NamespaceURI == null) throw NotWFError (String.Format ("'{0}' is undeclared namespace.", Prefix)); } } finally { MoveToElement (); } } for (int i = 0; i < attributeCount; i++) { if (!Object.ReferenceEquals (attributeTokens [i].Prefix, XmlNamespaceManager.PrefixXml)) continue; string aname = attributeTokens [i].LocalName; string value = attributeTokens [i].Value; switch (aname) { case "base": if (this.resolver != null) { Uri buri = BaseURI != String.Empty ? new Uri (BaseURI) : null; // xml:base="" without any base URI -> pointless. However there are // some people who use such xml:base. Seealso bug #608391. if (buri == null && String.IsNullOrEmpty (value)) break; Uri uri = resolver.ResolveUri ( buri, value); parserContext.BaseURI = uri != null ? uri.ToString () : String.Empty; } else parserContext.BaseURI = value; break; case "lang": parserContext.XmlLang = value; break; case "space": switch (value) { case "preserve": parserContext.XmlSpace = XmlSpace.Preserve; break; case "default": parserContext.XmlSpace = XmlSpace.Default; break; default: throw NotWFError (String.Format ("Invalid xml:space value: {0}", value)); } break; } } if (IsEmptyElement) CheckCurrentStateUpdate (); }
private void IncrementAttributeValueToken () { currentAttributeValue++; if (attributeValueTokens.Length == currentAttributeValue) { XmlTokenInfo [] newArray = new XmlTokenInfo [attributeValueTokens.Length * 2]; attributeValueTokens.CopyTo (newArray, 0); attributeValueTokens = newArray; } if (attributeValueTokens [currentAttributeValue] == null) attributeValueTokens [currentAttributeValue] = new XmlTokenInfo (this); currentAttributeValueToken = attributeValueTokens [currentAttributeValue]; currentAttributeValueToken.Clear (); }
private void SetTokenProperties ( XmlTokenInfo token, XmlNodeType nodeType, string name, string prefix, string localName, bool isEmptyElement, string value, bool clearAttributes) { token.NodeType = nodeType; token.Name = name; token.Prefix = prefix; token.LocalName = localName; token.IsEmptyElement = isEmptyElement; token.Value = value; this.elementDepth = depth; if (clearAttributes) ClearAttributes (); }