HtmlAgilityPack Attributes.Remove on Image Удаляет только один, когда их два

В нашем проекте я использую HtmlAgilityPack, чтобы отображать HTML-код из другой нашей системы. Я столкнулся с этой проблемой в своем модульном тестировании и хочу убедиться, что я не делаю что-то неправильно. Если у меня есть изображение, и оно имеет 2 значения «src», я бы хотел выбрать одно, удалить их оба и добавить одно обратно с правильным путем. Я не думаю, что это произойдет с нашим HTML, но на всякий случай....

Итак, вот пример тега изображения:

<img align=\"left\" alt=\"\" src=\"/blah.jpg\" src=\"/knowledge/blah.jpg\" border=\"0\" />

Вот код для управления Html:

    public static string FixHtmlLinks(this string html)
    {
        var htmlDoc = new HtmlDocument()
        {
            OptionWriteEmptyNodes = true
        };
        htmlDoc.LoadHtml(html);

        var imagesToCheck = htmlDoc.DocumentNode.SelectNodes("//img[@src!='']");

        if (null != imagesToCheck)
        {
            foreach (var image in imagesToCheck.ToList())
            {
                var src = image.GetAttributeValue("src", string.Empty);
                if (Uri.IsWellFormedUriString(src, UriKind.Relative))
                {
                    image.Attributes.Remove("src");
                    image.SetAttributeValue("src", string.Format(RELATIVE_IMAGE_PROTOCOL_AND_HOST, src));
                }
                else if (Uri.IsWellFormedUriString(src, UriKind.Absolute))
                {
                    image.Attributes.Remove("src");
                    image.SetAttributeValue("src", src.Replace(ABSOLUTE_IMAGE_HOST_TO_REPLACE, IMAGE_PROTOCOL_AND_HOST));
                }
            }
        }

        return htmlDoc.DocumentNode.OuterHtml;
    }

Когда я отлаживаю и добираюсь до строки "image.Attributes.Remove("src");", как и ожидалось, есть 2 значения "src". После того, как эта строка запустится, там будет 1 значение "src", то, которое начинается с "/knowledge". Однако я ожидаю, что они оба будут удалены, поскольку в сводке для удаления говорится:

Удаляет атрибут из списка, используя его имя. Если имеется более одного атрибута с таким именем, все они будут удалены.

Я проверил исходный код коллекции HtmlAttributeCollection в CodePlex и Метод Remove запускает цикл для удаления значений, так что все выглядит так, как будто оно должно работать.

Я использую это неправильно, или я нашел возможность предложить патч в HtmlAgilityPack?


person Lucas Fowler    schedule 20.06.2013    source источник
comment
Я хотел бы +4 к этому посту. Примеры: предварительное исследование, модульное тестирование и отказ от использования регулярных выражений для анализа HTML. :)   -  person TrueWill    schedule 20.06.2013
comment
Спасибо, я ценю это. Приятно видеть, что другие тоже заботятся об этом. :)   -  person Lucas Fowler    schedule 21.06.2013


Ответы (1)


Подтверждено: image.Attributes.Remove удаляет только первое вхождение.

Одним из быстрых решений является вызов Remove несколько раз. Если он вызывается, а атрибут не найден, он ничего не делает.

Вы можете сообщить об этом авторам HtmlAgilityPack.

person TrueWill    schedule 20.06.2013
comment
Спасибо, я ценю ваш ответ. Я обязательно дам им знать, и если у меня будет время, я посмотрю, смогу ли я найти исправление. - person Lucas Fowler; 21.06.2013