Станьте первыми 100 символов содержимого HTML, не разделяя теги

Существует много вопросов о том, как разделить теги HTML, но не многих на функциях/методах для закрытия их.

Вот ситуация. У меня есть 500 символьной Краткой информации о сообщениях (который включает теги HTML), но я только хочу первые 100 символов. Проблема состоит в том, если я усекаю сообщение, это могло бы быть посреди тега HTML..., который портит материал.

Принятие HTML является чем-то вроде этого:

<div class="bd">"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <br/>
 <br/>Some Dates: April 30 - May 2, 2010 <br/>
 <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. <em>Duis aute irure dolor in reprehenderit</em> in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. <br/>
 </p>
 For more information about Lorem Ipsum doemdloe, visit: <br/>
 <a href="http://www.somesite.com" title="Some Conference">Some text link</a><br/> 
</div>

Как я взял бы первые ~100 символов или так? (Хотя, идеально который был бы первым приблизительно 100 символов "СОДЕРЖАНИЯ" (промежуточный теги HTML)

Я принимаю лучший способ сделать, это было бы рекурсивным алгоритмом, который отслеживает теги HTML и добавляет любые теги, которые были бы усеченными, но это не может быть лучшим подходом.

Мои первые мысли используют рекурсию для подсчета вложенных тегов, и когда мы достигаем 100 символов, ищем следующее" <" и затем используем рекурсию для записи заключительных тегов HTML, необходимых оттуда.

Причина того, чтобы сделать это состоит в том, чтобы сделать краткое изложение существующих статей, не требуя, чтобы пользователь возвратился и предоставил сводки для всех статей. Я хочу сохранить форматирование HTML, если это возможно.

Примечание: Проигнорируйте, что HTML не является полностью семантическим. Это - то, с чем я должен иметь дело от моего WYSIWYG.

Править:

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

5
задан trejder 6 March 2015 в 15:25
поделиться

4 ответа

Я предлагаю найти удобный обходчик HTML (тот, который позволяет перемещаться по HTML, как XML), а затем, начиная с самого начала, теги игнорируют сами теги и подсчитывать только данные в теге. Подсчитайте это к своему пределу, а затем, когда он будет достигнут, просто закройте каждый тег (я не могу думать о каких-либо тегах, которые не являются просто тегом / чем-то еще).

Это должно работать достаточно хорошо и быть довольно близким к тому, что вы ищете.

Это совершенно не похоже на ol'noggin, поэтому я предполагаю, что будут некоторые хитрые части, такие как отображаемые значения атрибутов (например, значения тегов ссылок).

1
ответ дан 13 December 2019 в 22:05
поделиться

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

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

1
ответ дан 13 December 2019 в 22:05
поделиться

Что, если вы проанализируете HTML в структуре DOM, а затем начнете обход в ширину или сначала в глубину, что вам нравится, собирая текст узлов, пока не достигнете 100 символов?

3
ответ дан 13 December 2019 в 22:05
поделиться

Я решил использовать собственное решение ... просто для того, чтобы сделать это.

Если кто-нибудь увидит какие-либо логические ошибки или неэффективность, дайте мне знать.

Я не знаю, лучший ли это подход ... но, похоже, он работает. Вероятно, есть случаи, когда это не работает ... и, скорее всего, выйдет из строя, если html неверен.

/// <summary>
/// Get the first n characters of some html text
/// </summary>
private string truncateTo(string s, int howMany, string ellipsis) {

    // return entire string if it's more than n characters
    if (s.Length < howMany)
        return s;

    Stack<string> elements = new Stack<string>();
    StringBuilder sb = new StringBuilder();
    int trueCount = 0;

    for (int i = 0; i < s.Length; i++) {
        if (s[i] == '<') {

            StringBuilder elem = new StringBuilder();
            bool selfclosing = false;

            if (s[i + 1] == '/') {

                elements.Pop(); // Take the previous element off the stack
                while (s[i] != '>') {
                    i++;
                }
            }
            else { // not a closing tag so get the element name

                while (i < s.Length && s[i] != '>') {

                    if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {
                        elem.Append(s[i]);
                    }
                    else if (s[i] == '/' || s[i] == ' ') {

                        // self closing tag or end of tag name. Find the end of tag
                        do {
                            if (s[i] == '/' && s[i + 1] == '>') {
                                // at the end of self-closing tag. Don't store
                                selfclosing = true;
                            }

                            i++;
                        } while (i < s.Length && s[i] != '>');
                    }
                    i++;
                } // end while( != '>' )

                if (!selfclosing)
                    elements.Push(elem.ToString());
            } 
        }
        else {
            trueCount++;
            if (trueCount > howMany) {
                sb.Append(s.Substring(0, i - 1));
                sb.Append(ellipsis);
                while (elements.Count > 0) {
                    sb.AppendFormat("</{0}>", elements.Pop());
                }
            }
        }
    }

    return sb.ToString();
}
1
ответ дан 13 December 2019 в 22:05
поделиться
Другие вопросы по тегам:

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