/// <summary> /// Indents the specified line based on the current depth of the XML hierarchy. /// </summary> /// <param name="p_txaTextArea">The text area containing the line to indent.</param> /// <param name="p_intLineNumber">The line number of the line to indent.</param> /// <returns>The indent depth of the specified line.</returns> protected override int AutoIndentLine(TextArea p_txaTextArea, int p_intLineNumber) { XmlParser.TagStack stkTags = XmlParser.ParseTags(p_txaTextArea.Document, p_intLineNumber, null, null); Int32 intDepth = 0; Int32 intLastLineNum = -1; while (stkTags.Count > 0) { if (stkTags.Peek().LineNumber != intLastLineNum) { intLastLineNum = stkTags.Peek().LineNumber; intDepth++; } stkTags.Pop(); } StringBuilder stbLineWithIndent = new StringBuilder(); for (Int32 i = 0; i < intDepth; i++) { stbLineWithIndent.Append("\t"); } stbLineWithIndent.Append(TextUtilities.GetLineAsString(p_txaTextArea.Document, p_intLineNumber).Trim()); LineSegment oldLine = p_txaTextArea.Document.GetLineSegment(p_intLineNumber); Int32 intCaretOffset = stbLineWithIndent.Length - oldLine.Length; SmartReplaceLine(p_txaTextArea.Document, oldLine, stbLineWithIndent.ToString()); p_txaTextArea.Caret.Column += intCaretOffset; return(intDepth); }
/// <summary> /// Validates the XML against the schema. /// </summary> /// <returns><c>true</c> if the XML is valid; <c>false</c> otherwise.</returns> public bool ValidateXml() { m_tmrValidator.Stop(); IDocument docDocument = ActiveTextAreaControl.TextArea.Document; docDocument.MarkerStrategy.RemoveAll(x => { return(x.TextMarkerType == TextMarkerType.WaveLine); }); m_booMalformedXml = false; if (docDocument.TextLength == 0) { return(true); } XmlParser.TagStack stkBadTags = XmlParser.ParseTags(docDocument, docDocument.TotalNumberOfLines - 1, null, HighlightMalformedTag); //this deals with extra tags at beginning of file if ((stkBadTags.Count > 0) || m_booMalformedXml) { while (stkBadTags.Count > 0) { XmlParser.TagStack.TagPosition tpsTag = stkBadTags.Pop(); TextLocation tlcStart = new TextLocation(tpsTag.Column, tpsTag.LineNumber); TextLocation tlcEnd = new TextLocation(tpsTag.Column + tpsTag.Name.Length, tpsTag.LineNumber); HighlightMalformedTag(docDocument, tpsTag.Name, tlcStart, tlcEnd); } return(false); } Int32 intBadLineNum = Int32.MaxValue; using (XmlReader xrdValidator = XmlReader.Create(new StringReader(this.Text), m_xrsSettings)) { try { while (xrdValidator.Read()) { ; } if (m_booMalformedXml) { return(false); } } catch (XmlException err2) { intBadLineNum = err2.LineNumber; HighlightValidationErrors(err2.Message, new TextLocation(err2.LinePosition - 1, err2.LineNumber - 1)); } finally { xrdValidator.Close(); } } for (Int32 i = intBadLineNum; i < docDocument.TotalNumberOfLines; i++) { string strLine = docDocument.GetText(docDocument.GetLineSegment(i)); Int32 intLineNum = i; Int32 intLastOpenPos = strLine.LastIndexOf('<'); if (intLastOpenPos < 0) { continue; } Int32 intLastClosePos = strLine.LastIndexOf('>'); if ((intLastClosePos > -1) && (intLastOpenPos > intLastClosePos)) { string strNextLine = null; StringBuilder stbLines = new StringBuilder(strLine); //there is an open tag on this line - read lines until it is closed. for (; i < docDocument.TotalNumberOfLines; i++) { strNextLine = docDocument.GetText(docDocument.GetLineSegment(i)); intLastClosePos = strLine.LastIndexOf('>'); stbLines.Append(strNextLine); if (intLastClosePos < 0) { i--; break; } } strLine = stbLines.ToString(); } MatchCollection mclLineTags = rgxTagContents.Matches(strLine); foreach (Match mtcTag in mclLineTags) { string strTag = mtcTag.Groups[1].Value.Trim(); if (strTag.StartsWith("/")) { HighlightValidationErrors("Unexpected end tag.", new TextLocation(mtcTag.Groups[1].Index + 1, i)); } else { HighlightValidationErrors("Invalid tag.", new TextLocation(mtcTag.Groups[1].Index, i)); } } } return(intBadLineNum == Int32.MaxValue); }