public void Parse(string content)
{
int contentLength = content.Length;
if (contentLength == 0)
{
return;
}
lock (_parsingSynchronizer)
{
_innerContext = new InnerMarkupParsingContext(content);
_context = new MarkupParsingContext(_innerContext);
int endPosition = contentLength - 1;
int previousPosition = -1;
try
{
while (_innerContext.Position <= endPosition)
{
bool isProcessed = false;
int firstCharPosition = _innerContext.Position;
char firstCharValue;
bool firstCharExist = content.TryGetChar(firstCharPosition, out firstCharValue);
if (firstCharExist && firstCharValue == '<')
{
int secondCharPosition = firstCharPosition + 1;
char secondCharValue;
bool secondCharExist = content.TryGetChar(secondCharPosition, out secondCharValue);
if (secondCharExist)
{
if (IsTagFirstChar(secondCharValue))
{
// Start tag
isProcessed = ProcessStartTag();
}
else
{
int thirdCharPosition = secondCharPosition + 1;
char thirdCharValue;
bool thirdCharExist = content.TryGetChar(thirdCharPosition, out thirdCharValue);
if (thirdCharExist)
{
switch (secondCharValue)
{
case '/':
if (IsTagFirstChar(thirdCharValue))
{
// End tag
isProcessed = ProcessEndTag();
}
break;
case '!':
switch (thirdCharValue)
{
case '-':
int fourthCharPosition = thirdCharPosition + 1;
char fourthCharValue;
bool fourthCharExist = content.TryGetChar(
fourthCharPosition, out fourthCharValue);
if (fourthCharExist && fourthCharValue == '-')
{
// XML comments
isProcessed = ProcessComment();
}
break;
case '[':
// CDATA sections
isProcessed = ProcessCdataSection();
break;
case 'D':
case 'd':
// Doctype declaration
isProcessed = ProcessDoctype();
break;
}
break;
case '?':
// XML declaration and processing instructions
isProcessed = ProcessProcessingInstruction();
break;
}
}
}
}
}
if (!isProcessed)
{
// Text
ProcessText();
}
if (_innerContext.Position == previousPosition)
{
throw new MarkupParsingException(
string.Format(Strings.ErrorMessage_MarkupParsingFailed, "XML"),
_innerContext.NodeCoordinates, _innerContext.GetSourceFragment());
}
previousPosition = _innerContext.Position;
}
// Check whether there were not closed tags
if (_tagStack.Count > 0)
{
StackedXmlTag stackedTag = _tagStack.Pop();
throw new MarkupParsingException(
string.Format(Strings.ErrorMessage_NotClosedTag, stackedTag.Name),
stackedTag.Coordinates,
SourceCodeNavigator.GetSourceFragment(_innerContext.SourceCode, stackedTag.Coordinates));
}
}
catch (MarkupParsingException)
{
throw;
}
finally
{
_tagStack.Clear();
_context = null;
_innerContext = null;
}
}
}