public XMLFragmentElement TryParseNode() { if (_buffer.EndOfBuffer) return null; int startOuterXml = _buffer.Position; var token = NextToken(); if (token != "<") throw new XMLFragmentException("Expected \"<\", got "+token); XMLFragmentElement element = new XMLFragmentElement(); element.Name = NextToken(); while (true) { token = NextToken(); if (token == ">") break; else if (token == "/") // quick-exit case { NextToken(); element.OuterXml = TrimControl(_buffer.Buffer.Substring(startOuterXml, _buffer.Position - startOuterXml)).Trim(); element.InnerXml = ""; return element; } else { XMLFragmentAttribute attribute = new XMLFragmentAttribute(); attribute.Name = token; if ((token = NextToken()) != "=") throw new XMLFragmentException("Expected \"=\", got "+token); attribute.Value = NextToken(); element.Attributes.Add(attribute); } } while (true) { var oldPos = _buffer.Position; // for restoration below token = NextToken(); if (token == "<") { token = PeekToken(); if (token == "/") // finish element { NextToken(); // skip the / again token = NextToken(); NextToken(); // skip > element.OuterXml = TrimControl(_buffer.Buffer.Substring(startOuterXml, _buffer.Position - startOuterXml)).Trim(); element.InnerXml = TrimTags(element.OuterXml); if (token != element.Name) throw new XMLFragmentException("Mismatched element pairs: \""+element.Name+"\" vs \""+token+"\""); break; } else { _buffer.Position = oldPos; element.Elements.Add(TryParseNode()); } } else { // value, probably _buffer.Position = oldPos; element.Value = ReadUntil('<'); } } return element; }
public XMLFragmentElement TryParseNode() { if (_buffer.EndOfBuffer) { return(null); } int startOuterXml = _buffer.Position; var token = NextToken(); if (token != "<") { throw new XMLFragmentException("Expected \"<\", got " + token); } XMLFragmentElement element = new XMLFragmentElement(); element.Name = NextToken(); while (true) { token = NextToken(); if (token == ">") { break; } else if (token == "/") // quick-exit case { NextToken(); element.OuterXml = TrimControl(_buffer.Buffer.Substring(startOuterXml, _buffer.Position - startOuterXml)).Trim(); element.InnerXml = ""; return(element); } else { XMLFragmentAttribute attribute = new XMLFragmentAttribute(); attribute.Name = token; if ((token = NextToken()) != "=") { throw new XMLFragmentException("Expected \"=\", got " + token); } attribute.Value = NextToken(); element.Attributes.Add(attribute); } } while (true) { var oldPos = _buffer.Position; // for restoration below token = NextToken(); if (token == "<") { token = PeekToken(); if (token == "/") // finish element { NextToken(); // skip the / again token = NextToken(); NextToken(); // skip > element.OuterXml = TrimControl(_buffer.Buffer.Substring(startOuterXml, _buffer.Position - startOuterXml)).Trim(); element.InnerXml = TrimTags(element.OuterXml); if (token != element.Name) { throw new XMLFragmentException("Mismatched element pairs: \"" + element.Name + "\" vs \"" + token + "\""); } break; } else { _buffer.Position = oldPos; element.Elements.Add(TryParseNode()); } } else { // value, probably _buffer.Position = oldPos; element.Value = ReadUntil('<'); } } return(element); }