LifeAct
@LifeAct
Создаем и раскручиваем, не ставим на конвейер

Как заменить блок html текста?

Всем привет! Есть сайт на asp mvc и простенький html редактор, для ввода форматированного текста и вставки картинок. Появилась необходимость чтобы вставленные картинки увеличивались (lightbox), для этого нужно вместо картинки сделать ссылку картинки с определенным атрибутом. Вот как пытаюсь изменить готовый хтмл текст:

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(recordBL.Text); //recordBL.Text - тут хтмл текст
                 
                System.Text.StringBuilder txt = new System.Text.StringBuilder(recordBL.Text);

                var nodes = doc.DocumentNode.SelectNodes(@"//img[@src]");

                foreach (var img in nodes)
                {

                    
                    HtmlAgilityPack.HtmlAttribute att = img.Attributes["src"];
                    imgScrs.Add(att.Value);
					
					//формирую нужную ссылку/картинку
                    string readyLink = "<a href='" + att.Value + "' data-lightbox='lightbox-set'><img   src='" + att.Value + "'/></a>",
                    
					//это старая картинка
					old = img.OuterHtml;

					
					//и тут нужно заменить старую картинку, новой сформированной ссылкой-картинкой
                    recordBL.Text  = txt.Replace(old, readyLink).ToString();                    
                }


но Replace не отрабатывает, вероятно потому, что в old в дебаге при просмотре значения (клик на лупу) - old =
<img alt="" height="367" src="http://localhost:11733/Images/USERDATA/Posts/10-2017/u2t11102003.jpg" width="550">


а при просмотре без клика на лупу - joxi.ru/eAO4DQC4qbNpro
то есть экранируются двойные кавычки... других вариантов почему реплейс не отрабатывает нет

эти танцы с бубном можно и на стороне клиента через js сделать, но в js к сожалению не силен

---------UP
еще такой вариант:

string readyLink = "a href=\"" + att.Value + "\" data-lightbox=\"lightbox-set\"><img   src=\"" + att.Value + "\"/></a",
                        old = img.OuterHtml.ToString();

                    HtmlAgilityPack.HtmlNode aaa = doc.CreateElement(readyLink);

                    img.ParentNode.ReplaceChild(aaa, img);                
                   
                    recordBL.Text = doc.DocumentNode.OuterHtml;


но создаются две ссылки, вместо одной, видать родителя нет, так как я выбираю только картинки - var nodes = doc.DocumentNode.SelectNodes(@"//img[@src]");
  • Вопрос задан
  • 326 просмотров
Пригласить эксперта
Ответы на вопрос 2
@mpnj
Если отвечать на вопрос "как обойти экранирование"(ну вот, если у вас специфические вкусы:) ), то можно попробовать делать не Replace, а Remove.

Т.е. вы найдёте в вашем исходном тексте начало тега img по подстроке ""(или типа того). Получите из этих двух значений длину текста, который относится к этому тегу.
Дальше сделаете txt.Remove(startIndex, count).
Далее, вставите новое значение с помощью. txt.Insert(startIndex, readyLink) на место старого тега.
Тут самым "сложным" будет момент с тем,что у вас есть несколько тегов img,судя по наличию foreach.
Надеюсь, понятно объяснил мысль.

Ну а вообще да, сама глобальная проблема выглядит странно.
Ответ написан
Комментировать
@Free_ze
Пишу комментарии в комментарии, а не в ответы
то есть экранируются двойные кавычки...

Дебаггер дает вам удобное для копирования представление (если вы заметили, сама строка тоже обрамлена в кавычки), никакого экранирования в переменной на самом деле нет, это фишка нужна исключительно для литералов строк.

Вы уверены, что здесь правильно используется StringBuilder? Сейчас от него нет толка, ибо на каждой итерации цикла он возвращает и записывает строку, которая станет ненужной на следующей итерации, т.е. память все равно забивается, аллокации происходят. Какая-то преждевременная оптимизация.

Убедитесь, что он заменяемое значение действительно там содержится. HtmlAgilityPack вполне может оптимизировать HTML (тот, который из OuterHtml), скажем, вырезать пробелы и/или переводы строки.
Если вы работаете с DOM-парсером, то нужно не изобретать велосипеды, а пользоваться его API:
string htmlTag = "<foo>bar</foo>";
var newNode = HtmlNode.CreateNode( htmlTag );
img.ParentNode.ReplaceChild(newNode, img);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы