/// <summary> /// Visit an <see cref="XmlEmptyElementSyntax"/>. /// </summary> /// <param name="emptyElement"> /// The <see cref="XmlEmptyElementSyntax"/>. /// </param> /// <returns> /// The <see cref="XmlEmptyElementSyntax"/> (unchanged). /// </returns> public override SyntaxNode VisitXmlEmptyElement(XmlEmptyElementSyntax emptyElement) { Range elementRange = emptyElement.Span.ToNative(_textPositions); Range nameRange = emptyElement.NameNode?.Span.ToNative(_textPositions) ?? elementRange; Range attributesRange = emptyElement.AttributesNode?.FullSpan.ToNative(_textPositions) ?? elementRange; XSElement xsElement; if (String.IsNullOrWhiteSpace(emptyElement.Name)) { xsElement = new XSInvalidElement(emptyElement, elementRange, nameRange, attributesRange, parent: CurrentElement, hasContent: false); } else { xsElement = new XSEmptyElement(emptyElement, elementRange, nameRange, attributesRange, parent: CurrentElement); } if (xsElement.ParentElement is XSElementWithContent parentElement) { parentElement.Content = parentElement.Content.Add(xsElement); } PushElement(xsElement); foreach (XmlAttributeSyntax attribute in emptyElement.AsSyntaxElement.Attributes) { Visit(attribute); } PopElement(); return(emptyElement); }
/// <summary> /// Visit an <see cref="XmlElementSyntax"/>. /// </summary> /// <param name="element"> /// The <see cref="XmlElementSyntax"/>. /// </param> /// <returns> /// The <see cref="XmlElementSyntax"/> (unchanged). /// </returns> public override SyntaxNode VisitXmlElement(XmlElementSyntax element) { Range elementRange = element.Span.ToNative(_textPositions); Range nameRange = element.NameNode?.Span.ToNative(_textPositions) ?? elementRange; Range openingTagRange = element.StartTag?.Span.ToNative(_textPositions) ?? elementRange; Range attributesRange = element.AttributesNode?.FullSpan.ToNative(_textPositions) ?? elementRange; Range closingTagRange = element.EndTag?.Span.ToNative(_textPositions) ?? elementRange; Range contentRange; if (openingTagRange.End <= closingTagRange.Start) { contentRange = new Range( start: openingTagRange.End, end: closingTagRange.Start ); } else { contentRange = elementRange; } // All the ways an XML element can go wrong. XSElement xsElement; if (String.IsNullOrWhiteSpace(element.Name)) { if (element.StartTag.Width == 2) // <> surrounded by whitespace { xsElement = new XSInvalidElement(element, openingTagRange, nameRange, attributesRange: openingTagRange, parent: CurrentElement, hasContent: false); } else if (element.EndTag == null) // << { xsElement = new XSInvalidElement(element, openingTagRange, nameRange, attributesRange: openingTagRange, parent: CurrentElement, hasContent: false); } else if (element.EndTag.Width == 0) // <> after an element { openingTagRange = new Range( _textPositions.GetPosition(element.Span.Start), _textPositions.GetPosition(element.Span.Start + 1) ); xsElement = new XSInvalidElement(element, openingTagRange, nameRange, attributesRange: openingTagRange, parent: CurrentElement, hasContent: false); } else // F**k knows. { xsElement = new XSInvalidElement(element, elementRange, nameRange, attributesRange: openingTagRange, parent: CurrentElement, hasContent: true); } } else if (String.IsNullOrWhiteSpace(element.EndTag.Name)) // <XXX> with no </XXX> { xsElement = new XSInvalidElement(element, openingTagRange, nameRange, attributesRange: openingTagRange, parent: CurrentElement, hasContent: false); } else { xsElement = new XSElementWithContent(element, elementRange, nameRange, openingTagRange, attributesRange, contentRange, closingTagRange, parent: CurrentElement); } if (xsElement.ParentElement is XSElementWithContent parentElement) { parentElement.Content = parentElement.Content.Add(xsElement); } PushElement(xsElement); foreach (XmlAttributeSyntax attribute in element.AsSyntaxElement.Attributes) { Visit(attribute); } if (element.Content is SyntaxList childElements) { foreach (XmlElementSyntaxBase childElement in childElements.ChildNodes.OfType <XmlElementSyntaxBase>()) { Visit(childElement); } } else if (element.Content is XmlElementSyntaxBase singleChildElement) { Visit(singleChildElement); } else if (element.Content is XmlTextSyntax text) { VisitXmlText(text); } PopElement(); return(element); }