Привет!
В вашем случае все не так просто. Скорее всего вам нужно написать еще один лексер =)
Процесс будет выглядеть так:
1) Берем исходную xml ноду
<Table><TAB|LE CELLSPACIN|(0)G=0 CELLPADDIN=0 CLASS=PDS_COMBO_TABLE></TABLE></Table>
2) В injected psi провайдере переопределяем лексер, который будет лексировать ноды, после его прохода, строка должна выглядеть как-то так:
<TABLE CELLSPACING=0 CELLPADDIN=0 CLASS=PDS_COMBO_TABLE></TABLE>
3) Полученную строку отдаем HTML лексеру/парсеру, с которыми он прекрасно справляется
Теперь про лексер. Пусть у нас есть HtmlLexer : ILexer
Сделаем декоратор над этим лексером MySuperLexer : ILexer, который будум использовать вместо оригинального HtmlLexer в inject psi провайдере
Сам MySuperLexer будет:
1) преобразовывать нашу строку к обычной html строке (выпиливать эскейпинг)
2) по построенной html строке создавать новый лексер и делегировать ему операции Start, Advance и т.д.
3) при запросах TokenStart и TokenEnd он должен отдавать настоящие координаты токена внутри оригинальной строки
Прототип:
public class MySuperLexer : ILexer
{
private readonly IBuffer myOriginalBuffer;
private readonly RangeTranslator myRangeTranslator;
private readonly HtmlLexer myHtmlLexer;
public ClrRegexLexer(IBuffer originalBuffer)
{
myOriginalBuffer = originalBuffer;
var htmlString = HtmlUtil.Parse(originalBuffer, out myRangeTranslator);
var buffer = new StringBuffer(htmlString);
myHtmlLexer = new HtmlLexer(buffer);
}
public void Start()
{
myHtmlLexer.Start();
}
public void Advance()
{
myHtmlLexer.Advance();
}
object ILexer.CurrentPosition
{
get { return myHtmlLexer.CurrentPosition; }
set { myHtmlLexer.CurrentPosition = value; }
}
public TokenNodeType TokenType
{
get { return myHtmlLexer.TokenType; }
}
public int TokenStart
{
get
{
return myRangeTranslator.GetSourceRange(new TextRange(myHtmlLexer.TokenStart, myHtmlLexer.TokenEnd)).StartOffset;
}
}
public int TokenEnd
{
get
{
return myRangeTranslator.GetSourceRange(myHtmlLexer.TokenEnd - 1).EndOffset;
}
}
public IBuffer Buffer
{
get { return myOriginalBuffer; }
}
}
Класс RangeTranslator предназначен для хранения информации о взаимном расположении символов в двух строках.
Метод HtmlUtil.Parse вам предстоит написать, или найти что-то похожее, я затрудняюсь сказать делали мы где-то такое или нет. Наверное делали =)
За образец можете взять ClrRegexLexer и логику из CSharpLiteralWrapper.
Аналогично вы сможете склеивать результирующую строку из кусочком, только нужно правильно ренжи сохранять =)
Если будут какие-то специфичные вопросы, пишите мне в скайп skype.stepanov.ev