Как уменьшить размер строки HTML - PullRequest
1 голос
/ 23 октября 2009

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

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

Ребята, у вас есть идея уменьшить длину строки html и вывести html в хорошем формате?

Например:

следующий html-текст является описанием 0123456789

**

Если я хочу отобразить до 5 символов, результат, который я хочу увидеть, будет 01234

так что вы будете делать, чтобы получить правильный.

PS: помните, что это самая простая ситуация.

Ответы [ 5 ]

1 голос
/ 18 апреля 2012
1 голос
/ 23 октября 2009

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

С другой стороны, почему бы не иметь то, что генерирует html, сначала ограничьте размер текста для начала. Таким образом, вам не нужно беспокоиться о том, чтобы извлечь текст из html и сократить его.

Сказав это, трудно сказать больше без примера кода ...

0 голосов
/ 23 октября 2009

Но вы генерируете описание откуда-то или получаете полный html из другого источника. Если вы генерируете описание продукта, я думаю, что вы должны выполнить свою обрезку, прежде чем вставлять его в HTML-код, возвращая его.

В вашем вопросе прямо не говорится, что вы получаете html-код из другого источника, поэтому я считаю, что приведенное выше предложение является самым простым решением

0 голосов
/ 23 октября 2009

я бы сделал так:

  string value = "<p class=\"abc-class\">0123456789</p>";
  char[] delimiters = new char[] { '<', '>' };
    string[] parts = value.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
  string value2 = parts[1].ToString();
  //
  // here you do what you want to value2
  //

  Console.WriteLine(delimiters[0]+parts[0]+delimiters[1]+value2+delimiters[0]+parts[2]+delimiters[1]);
  Console.WriteLine(value);

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

разбиение строки таким способом быстрее, чем при использовании строки. split ('')

надеюсь, что это соответствует вашим потребностям!

0 голосов
/ 23 октября 2009

Это может быть сделано (и я сделал это), но это все еще оставляет потенциал для странной визуализации разметки, особенно когда применяются стили CSS. Когда я писал это, я делал это в Javascript, но тот же подход и все еще использовался и включает работу с DOM, а не String .

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

Вы можете свободно использовать любые идеи / стратегии / коды, которые вы считаете нужными ниже.

/*
    Given a DOM Node truncate the contained text at a certain length.
    The truncation happens in a depth-first manner.

    Any elements that exist past the exceeded length are removed
    (this includes all future children, siblings, cousins and whatever else)
    and the text in the element in which the exceed happens is truncated.

    NOTES:
    - This modifieds the original node.
    - This only supports ELEMENT and TEXT node types (other types are ignored)

    This function return true if the limit was reached.
*/
truncateNode : function (rootNode, limit, ellipses) {
    if (arguments.length < 3) {
        ellipses = "..."
    }

    // returns the length found so far.
    // if found >= limit then all FUTURE nodes should be removed
    function truncate (node, found) {
        var ELEMENT_NODE = 1
        var TEXT_NODE = 3

        switch (node.nodeType) {
            case ELEMENT_NODE:
                var child = node.firstChild
                while (child) {
                    found = truncate(child, found)
                    if (found >= limit) {
                        // remove all FUTURE elements
                        while (child.nextSibling) {
                            child.parentNode.removeChild(child.nextSibling)
                        }
                    }
                    child = child.nextSibling
                }
                return found
            case TEXT_NODE:
                var remaining = limit - found
                if (node.nodeValue.length < remaining) {
                    // still room for more (at least one more letter)
                    return found + node.nodeValue.length
                }
                node.nodeValue = node.nodeValue.substr(0, remaining) + ellipses
                return limit
            default:
                // no nothing
        }
    }

    return truncate(rootNode, 0)    
},

Ну, мне правда скучно. Вот это в C #. Почти то же самое. Все еще должно быть обновлено, чтобы быть немутативным. Упражнение для читателя, бла, бла ...

class Util
{

    public static string
    LazyWrapper (string html, int limit) {
        var d = new XmlDocument();
        d.InnerXml = html;
        var e = d.FirstChild;
        Truncate(e, limit);
        return d.InnerXml;
    }

    public static void
    Truncate(XmlNode node, int limit) {
        TruncateHelper(node, limit, 0);
    }

    public static int
    TruncateHelper(XmlNode node, int limit, int found) {
        switch (node.NodeType) {
        case XmlNodeType.Element:
            var child = node.FirstChild;
            while (child != null) {
                found = TruncateHelper(child, limit, found);
                if (found >= limit) {
                    // remove all FUTURE elements
                    while (child.NextSibling != null) {
                        child.ParentNode.RemoveChild(child.NextSibling);
                    }
                }
                child = child.NextSibling;
            }
            return found;
        case XmlNodeType.Text:
            var remaining = limit - found;
            if (node.Value.Length < remaining) {
                // still room for more (at least one more letter)
                return found + node.Value.Length;
            }
            node.Value = node.Value.Substring(0, remaining);
            return limit;
        default:
            return found;
        }
    }

}

Использование и результат:

Util.LazyWrapper(@"<p class=""abc-class"">01<x/>23456789<y/></p>", 5)
// => <p class="abc-class">01<x />234</p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...