Re[5]: [Resharper SDK] Распарсить html сохранённый в xml.
От: DragonFire Россия  
Дата: 18.06.15 12:33
Оценка:
Привет!

В вашем случае все не так просто. Скорее всего вам нужно написать еще один лексер =)
Процесс будет выглядеть так:
1) Берем исходную xml ноду
<Table>&lt;TAB|LE CELLSPACIN|(0)G=0 CELLPADDIN=0 CLASS=PDS_COMBO_TABLE&gt;&lt;/TABLE&gt;</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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.