Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
отч.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
796 Кб
Скачать
☆

1.3Работа с файлами html в с#

Выполнить обрезку HTML тегов с помощью C# можно многими способами, но каждый имеет свои премущества и недостатки, особенности реализации и дополнительные ньюансы. В этой статье я хочу доступно объяснить те подходы к решению этой задачи, которые помогли мне, и показать какие ньюансы могут возникнуть при их использовании.

Для начала нужно уточнить что же такое обрезка HTML тегов и зачем она нужна. Под обрезкой тегов я понимаю полное или частичное удаление HTML тегов из строки. Говоря про частичное удаление, я подразумеваю оставление тех тегов и их атрибутов, которые находятся в белом списке, тоесть в списке разрешенных тегов. Понадобиться такая операция вам может, например, если при оставлении комментария на вашем сайте вы хотите разрешить пользователю вводить только некоторый ограниченный набор HTML тегов. Или же вы могли спарсить HTML контент из какого то источника, и при вставке его на свой сайт также хотите оставить только некоторые теги (<p>,<br />, <strong>, …).

Для тестов будем использовать следующую строку:

1

<div><p style='text-align:center;'>Some <font size='3' color='red'>text in font</font> - another <br /> <customAttr>text in custom attribute</customAttr> <br> More Text</p><div>

Элементарная обрезка с помощью регулярных выражений

Если надо полностью обрезать все без исключения HTML теги из строки, то можно воспользоваться одним простым и элегантным решением на основе несложного регулярного выражения:

1

static string StripHtmlTagsUsingRegex(string inputString)

2

{

3

return Regex.Replace(inputString, @"<[^>]*>", String.Empty);

4

}

Для рассматриваемой нами входной строки этот метод вернет такой результат:

1

Some text in font - another text in custom attribute More Text

Данное простое регулярное выражение можно немного усовершенствовать, что бы иметь возможность оставить некоторые теги:

1

static string StripHtmlTagsUsingRegex(string inputString)

2

{

3

return Regex.Replace(inputString, @"<(?!br|p|\/p)[^>]*>", String.Empty);

4

}

Тогда получим такой результат, где будут сохранены теги <p> и <br/>:

1

<p style='text-align:center;'>Some text in font - another <br /> text in custom attribute <br> More Text</p>

Но как видим, оставляя теги, мы оставляем также все их атрибуты. Можно конечно продолжить расширение нашего простого регулярного выражения, но тогда оно будет уже не очень простым.

Если уж вам нужна какая то более изощренная обрезка тегов, то лучше не экспериментировать, а использовать уже готовые оттестированные решения.

Дальше я представлю несколько вариантов, которые я нашел в сети.

Обрезка с помощью Html Agility Pack

Если поискать решение задачи которая является темой этой статьи, то не cложно заметить, что на многих сайтах предлагают использовать Html Agility Pack (HAP). Эта библиотека позволяет в удобной форме работать с DOM деревом HTML документа, и ее использование вполне целесообразно.

Вот интересный пример взятый отсюда:

/// <summary>

02

/// Filters HTML to the valid html tags set (with only the attributes specified)

03

///

04

/// Thanks to http://refactormycode.com/codes/333-sanitize-html for the original

05

/// </summary>

06

public static class HtmlSanitizeExtension

07

{

08

private const string HTML_TAG_PATTERN = @"(?'tag_start'</?)(?'tag'\w+)((\s+(?'attr'(?'attr_name'\w+)(\s*=\s*(?:"".*?""|'.*?'|[^'"">\s]+)))?)+\s*|\s*)(?'tag_end'/?>)";

09

10

/// <summary>

11

/// A dictionary of allowed tags and their respectived allowed attributes. If no

12

/// attributes are provided, all attributes will be stripped from the allowed tag

13

/// </summary>

14

public static Dictionary<string, List<string>> ValidHtmlTags = new Dictionary<string, List<string>> {

15

{ "p", new List<string>() },

16

{ "br", new List<string>() },

17

{ "strong", new List<string>() },

18

{ "ul", new List<string>() },

19

{ "li", new List<string>() },

20

{ "a", new List<string> { "href", "target" } }

21

};

22

23

/// <summary>

24

/// Extension filters your HTML to the whitelist specified in the ValidHtmlTags dictionary

25

/// </summary>

26

public static string FilterHtmlToWhitelist(this string text)

27

{

28

Regex htmlTagExpression = new Regex(HTML_TAG_PATTERN, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled);

29

30

return htmlTagExpression.Replace(text, m =>

31

{

32

if (!ValidHtmlTags.ContainsKey(m.Groups["tag"].Value))

33

return String.Empty;

34

35

StringBuilder generatedTag = new StringBuilder(m.Length);

36

37

Group tagStart = m.Groups["tag_start"];

38

Group tagEnd = m.Groups["tag_end"];

39

Group tag = m.Groups["tag"];

40

Group tagAttributes = m.Groups["attr"];

41

42

generatedTag.Append(tagStart.Success ? tagStart.Value : "<");

43

generatedTag.Append(tag.Value);

44

45

foreach (Capture attr in tagAttributes.Captures)

46

{

47

int indexOfEquals = attr.Value.IndexOf('=');

48

49

// don't proceed any futurer if there is no equal sign or just an equal sign

50

if (indexOfEquals < 1)

51

continue;

52

53

string attrName = attr.Value.Substring(0, indexOfEquals);

54

55

// check to see if the attribute name is allowed and write attribute if it is

56

if (ValidHtmlTags[tag.Value].Contains(attrName))

57

{

58

generatedTag.Append(' ');

59

generatedTag.Append(attr.Value);

60

}

61

}

62

63

generatedTag.Append(tagEnd.Success ? tagEnd.Value : ">");

64

65

return generatedTag.ToString();

66

});

67

}

68

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]