private void ParseCallback(XmlReader reader) { if (reader.NodeType == XmlNodeType.Element) { string localName = reader.LocalName; if (XmlNames.ElementEquals(localName, XmlNames.ExampleElementName) && comment.ExampleText == null) { comment.ExampleText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.SummaryElementName) && comment.SummaryText == null) { comment.SummaryText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.ReturnsElementName) && comment.ReturnsText == null) { comment.ReturnsText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.RemarksElementName) && comment.RemarksText == null) { comment.RemarksText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.ParameterElementName)) { string name = reader.GetAttribute(XmlNames.NameAttributeName); string paramText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !comment.parameterTexts.ContainsKey(name)) { (parameterNamesBuilder ?? (parameterNamesBuilder = ImmutableArray.CreateBuilder <string>())).Add(name); comment.parameterTexts.Add(name, paramText.Trim()); // TODO: trim each line } } else if (XmlNames.ElementEquals(localName, XmlNames.TypeParameterElementName)) { string name = reader.GetAttribute(XmlNames.NameAttributeName); string typeParamText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !comment.typeParameterTexts.ContainsKey(name)) { (typeParameterNamesBuilder ?? (typeParameterNamesBuilder = ImmutableArray.CreateBuilder <string>())).Add(name); comment.typeParameterTexts.Add(name, typeParamText.Trim()); // TODO: trim each line } } else if (XmlNames.ElementEquals(localName, XmlNames.ExceptionElementName)) { string type = reader.GetAttribute(XmlNames.CrefAttributeName); string exceptionText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(type)) { if (exceptionTextBuilders == null || !exceptionTextBuilders.ContainsKey(type)) { (exceptionTypesBuilder ?? (exceptionTypesBuilder = ImmutableArray.CreateBuilder <string>())).Add(type); (exceptionTextBuilders ?? (exceptionTextBuilders = new Dictionary <string, ImmutableArray <string> .Builder>())).Add(type, ImmutableArray.CreateBuilder <string>()); } exceptionTextBuilders[type].Add(exceptionText); } } else if (XmlNames.ElementEquals(localName, XmlNames.CompletionListElementName)) { string cref = reader.GetAttribute(XmlNames.CrefAttributeName); if (!string.IsNullOrWhiteSpace(cref)) { comment.CompletionListCref = cref; } reader.ReadInnerXml(); } else { // This is an element we don't handle. Skip it. reader.Read(); } } else { // We came across something that isn't a start element, like a block of text. // Skip it. reader.Read(); } }
private void ParseCallback(XmlReader reader) { if (reader.NodeType == XmlNodeType.Element) { var localName = reader.LocalName; if (XmlNames.ElementEquals(localName, XmlNames.ExampleElementName) && _comment.ExampleText == null) { _comment.ExampleText = TrimEachLine(reader.ReadInnerXml()); } else if (XmlNames.ElementEquals(localName, XmlNames.SummaryElementName) && _comment.SummaryText == null) { _comment.SummaryText = TrimEachLine(reader.ReadInnerXml()); } else if (XmlNames.ElementEquals(localName, XmlNames.ReturnsElementName) && _comment.ReturnsText == null) { _comment.ReturnsText = TrimEachLine(reader.ReadInnerXml()); } else if (XmlNames.ElementEquals(localName, XmlNames.ValueElementName) && _comment.ValueText == null) { _comment.ValueText = TrimEachLine(reader.ReadInnerXml()); } else if (XmlNames.ElementEquals(localName, XmlNames.RemarksElementName) && _comment.RemarksText == null) { _comment.RemarksText = TrimEachLine(reader.ReadInnerXml()); } else if (XmlNames.ElementEquals(localName, XmlNames.ParameterElementName)) { var name = reader.GetAttribute(XmlNames.NameAttributeName); var paramText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !_comment._parameterTexts.ContainsKey(name)) { (_parameterNamesBuilder ?? (_parameterNamesBuilder = ImmutableArray.CreateBuilder <string>())).Add(name); _comment._parameterTexts.Add(name, TrimEachLine(paramText)); } } else if (XmlNames.ElementEquals(localName, XmlNames.TypeParameterElementName)) { var name = reader.GetAttribute(XmlNames.NameAttributeName); var typeParamText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !_comment._typeParameterTexts.ContainsKey(name)) { (_typeParameterNamesBuilder ?? (_typeParameterNamesBuilder = ImmutableArray.CreateBuilder <string>())).Add(name); _comment._typeParameterTexts.Add(name, TrimEachLine(typeParamText)); } } else if (XmlNames.ElementEquals(localName, XmlNames.ExceptionElementName)) { var type = reader.GetAttribute(XmlNames.CrefAttributeName); var exceptionText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(type)) { if (_exceptionTextBuilders == null || !_exceptionTextBuilders.ContainsKey(type)) { (_exceptionTypesBuilder ?? (_exceptionTypesBuilder = ImmutableArray.CreateBuilder <string>())).Add(type); (_exceptionTextBuilders ?? (_exceptionTextBuilders = new Dictionary <string, ImmutableArray <string> .Builder>())).Add(type, ImmutableArray.CreateBuilder <string>()); } _exceptionTextBuilders[type].Add(exceptionText); } } else if (XmlNames.ElementEquals(localName, XmlNames.CompletionListElementName)) { var cref = reader.GetAttribute(XmlNames.CrefAttributeName); if (!string.IsNullOrWhiteSpace(cref)) { _comment.CompletionListCref = cref; } reader.ReadInnerXml(); } else { // This is an element we don't handle. Skip it. reader.Read(); } } else { // We came across something that isn't a start element, like a block of text. // Skip it. reader.Read(); } }
/// <summary> /// Parses and constructs a <see cref="DocumentationComment" /> from the given fragment of XML. /// </summary> /// <param name="xml">The fragment of XML to parse.</param> /// <returns>A DocumentationComment instance.</returns> public static DocumentationComment FromXmlFragment(string xml) { try { // TODO: probably want to preserve whitespace (DevDiv #13045). XmlReader reader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }); DocumentationComment comment = new DocumentationComment(); comment.FullXmlFragment = xml; List <string> parameterNamesBuilder = new List <string>(); List <string> typeParameterNamesBuilder = new List <string>(); List <string> exceptionTypesBuilder = new List <string>(); try { Dictionary <string, List <string> > exceptionTextBuilders = new Dictionary <string, List <string> >(); while (!reader.EOF) { if (reader.IsStartElement()) { string localName = reader.LocalName; if (XmlNames.ElementEquals(localName, XmlNames.ExampleElementName) && comment.ExampleText == null) { comment.ExampleText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.SummaryElementName) && comment.SummaryText == null) { comment.SummaryText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.ReturnsElementName) && comment.ReturnsText == null) { comment.ReturnsText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.RemarksElementName) && comment.RemarksText == null) { comment.RemarksText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.ParameterElementName)) { string name = reader.GetAttribute(XmlNames.NameAttributeName); string paramText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !comment.parameterTexts.ContainsKey(name)) { parameterNamesBuilder.Add(name); comment.parameterTexts.Add(name, paramText.Trim()); // TODO: trim each line } } else if (XmlNames.ElementEquals(localName, XmlNames.TypeParameterElementName)) { string name = reader.GetAttribute(XmlNames.NameAttributeName); string typeParamText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !comment.typeParameterTexts.ContainsKey(name)) { typeParameterNamesBuilder.Add(name); comment.typeParameterTexts.Add(name, typeParamText.Trim()); // TODO: trim each line } } else if (XmlNames.ElementEquals(localName, XmlNames.ExceptionElementName)) { string type = reader.GetAttribute(XmlNames.CrefAttributeName); string exceptionText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(type)) { if (!exceptionTextBuilders.ContainsKey(type)) { exceptionTypesBuilder.Add(type); exceptionTextBuilders.Add(type, new List <string>()); } exceptionTextBuilders[type].Add(exceptionText); } } else if (XmlNames.ElementEquals(localName, XmlNames.CompletionListElementName)) { string cref = reader.GetAttribute(XmlNames.CrefAttributeName); if (!string.IsNullOrWhiteSpace(cref)) { comment.CompletionListCref = cref; } reader.ReadInnerXml(); } else { // This is an element we don't handle. Skip it. reader.Read(); } } else { // We came across something that isn't a start element, like a block of text. // Skip it. reader.Read(); } } foreach (var typeAndBuilderPair in exceptionTextBuilders) { comment.exceptionTexts.Add(typeAndBuilderPair.Key, typeAndBuilderPair.Value.AsImmutable()); } } finally { comment.ParameterNames = parameterNamesBuilder.AsImmutable(); comment.TypeParameterNames = typeParameterNamesBuilder.AsImmutable(); comment.ExceptionTypes = exceptionTypesBuilder.AsImmutable(); } return(comment); } catch (Exception) { // It would be nice if we only had to catch XmlException to handle invalid XML // while parsing doc comments. Unfortunately, other exceptions can also occur, // so we just catch them all. See Dev12 Bug 612456 for an example. return(new DocumentationComment { FullXmlFragment = xml, HadXmlParseError = true }); } }