c # Обрезать HTML безопасно для резюме статьи

У кого-нибудь есть вариация c # этого?

Это так, я могу взять HTML-код и отображать его без разбора в качестве сводного руководства к статье?

Обрезать текст, содержащий HTML, игнорируя теги

Спаси меня от изобретения колеса!

редактировать

Извините, новость здесь и ваше право, лучше бы сформулировать вопрос, вот немного больше информации

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

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

Идея, которую я имею для решения, состоит в том, чтобы

сначала обрежьте слова html до N (слова лучше, но символы в порядке) (не останавливайтесь на середине тега и не обрезайте атрибут require)

работать через открытые теги html в этой усеченной строке (может быть, вставьте их в стек, как я иду?)

затем проработайте закрывающие теги и убедитесь, что они совпадают с теми, что находятся в стеке, как я их выкину?

если после этого в стеке остались какие-либо открытые теги, запишите их в конец усеченной строки, и html должен быть хорош!

Изменить 12/11/2009Вот то, что я собрал вместе в файле unittest в VS2008, этоможет' помогите кому-нибудь в будущемМои попытки взлома, основанные на коде Яна, на вершине для версии char + word version (ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: это грязный грубый код !! с моей стороны)Я предполагаю работать схорошо сформированный» HTML во всех случаях (но не обязательно полный документ с корневым узлом согласно версии XML)XML-версия Abels находится в самом низу, но еще не дошла до полного запуска тестов для этого (плюс нужно понимать код) ...Я буду обновлять, когда я получу шанс уточнитьвозникли проблемы с размещением кода? нет ли возможности загрузки в стек?

Спасибо за все комментарии :)

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.XPath;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace PINET40TestProject
{
    [TestClass]
    public class UtilityUnitTest
    {
        public static string TruncateHTMLSafeishChar(string text, int charCount)
        {
            bool inTag = false;
            int cntr = 0;
            int cntrContent = 0;

            // loop through html, counting only viewable content
            foreach (Char c in text)
            {
                if (cntrContent == charCount) break;
                cntr++;
                if (c == '')
                {
                    inTag = false;
                    continue;
                }
                if (!inTag) cntrContent++;
            }

            string substr = text.Substring(0, cntr);

            //search for nonclosed tags        
            MatchCollection openedTags = new Regex("").Matches(substr);
            MatchCollection closedTags = new Regex("").Matches(substr);

            // create stack          
            Stack opentagsStack = new Stack();
            Stack closedtagsStack = new Stack();

            // to be honest, this seemed like a good idea then I got lost along the way 
            // so logic is probably hanging by a thread!! 
            foreach (Match tag in openedTags)
            {
                string openedtag = tag.Value.Substring(1, tag.Value.Length - 2);
                // strip any attributes, sure we can use regex for this!
                if (openedtag.IndexOf(" ") >= 0)
                {
                    openedtag = openedtag.Substring(0, openedtag.IndexOf(" "));
                }

                // ignore brs as self-closed
                if (openedtag.Trim() != "br")
                {
                    opentagsStack.Push(openedtag);
                }
            }

            foreach (Match tag in closedTags)
            {
                string closedtag = tag.Value.Substring(2, tag.Value.Length - 3);
                closedtagsStack.Push(closedtag);
            }

            if (closedtagsStack.Count < opentagsStack.Count)
            {
                while (opentagsStack.Count > 0)
                {
                    string tagstr = opentagsStack.Pop();

                    if (closedtagsStack.Count == 0 || tagstr != closedtagsStack.Peek())
                    {
                        substr += "";
                    }
                    else
                    {
                        closedtagsStack.Pop();
                    }
                }
            }

            return substr;
        }

        public static string TruncateHTMLSafeishWord(string text, int wordCount)
        {
            bool inTag = false;
            int cntr = 0;
            int cntrWords = 0;
            Char lastc = ' ';

            // loop through html, counting only viewable content
            foreach (Char c in text)
            {
                if (cntrWords == wordCount) break;
                cntr++;
                if (c == '')
                {
                    inTag = false;
                    continue;
                }
                if (!inTag)
                {
                    // do not count double spaces, and a space not in a tag counts as a word
                    if (c == 32 && lastc != 32)
                        cntrWords++;
                }
            }

            string substr = text.Substring(0, cntr) + " ...";

            //search for nonclosed tags        
            MatchCollection openedTags = new Regex("").Matches(substr);
            MatchCollection closedTags = new Regex("").Matches(substr);

            // create stack          
            Stack opentagsStack = new Stack();
            Stack closedtagsStack = new Stack();

            foreach (Match tag in openedTags)
            {
                string openedtag = tag.Value.Substring(1, tag.Value.Length - 2);
                // strip any attributes, sure we can use regex for this!
                if (openedtag.IndexOf(" ") >= 0)
                {
                    openedtag = openedtag.Substring(0, openedtag.IndexOf(" "));
                }

                // ignore brs as self-closed
                if (openedtag.Trim() != "br")
                {
                    opentagsStack.Push(openedtag);
                }
            }

            foreach (Match tag in closedTags)
            {
                string closedtag = tag.Value.Substring(2, tag.Value.Length - 3);
                closedtagsStack.Push(closedtag);
            }

            if (closedtagsStack.Count < opentagsStack.Count)
            {
                while (opentagsStack.Count > 0)
                {
                    string tagstr = opentagsStack.Pop();

                    if (closedtagsStack.Count == 0 || tagstr != closedtagsStack.Peek())
                    {
                        substr += "";
                    }
                    else
                    {
                        closedtagsStack.Pop();
                    }
                }
            }

            return substr;
        }

        public static string TruncateHTMLSafeishCharXML(string text, int charCount)
        {
            // your data, probably comes from somewhere, or as params to a methodint 
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(text);
            // create a navigator, this is our primary tool
            XPathNavigator navigator = xml.CreateNavigator();
            XPathNavigator breakPoint = null;

            // find the text node we need:
            while (navigator.MoveToFollowing(XPathNodeType.Text))
            {
                string lastText = navigator.Value.Substring(0, Math.Min(charCount, navigator.Value.Length));
                charCount -= navigator.Value.Length;
                if (charCount 

Ответы на вопрос(4)

Ваш ответ на вопрос