HtmlAgilityPack: как создать отступ HTML? - PullRequest
8 голосов
/ 09 мая 2011

Итак, я генерирую HTML, используя HtmlAgilityPack, и он работает отлично, но текст HTML не имеет отступов.Однако я могу получить XML с отступом, но мне нужен HTML.Есть ли способ?

HtmlDocument doc = new HtmlDocument();

// gen html
HtmlNode table = doc.CreateElement("table");
table.Attributes.Add("class", "tableClass");
HtmlNode tr = doc.CreateElement("tr");
table.ChildNodes.Append(tr);
HtmlNode td = doc.CreateElement("td");
td.InnerHtml = "—";
tr.ChildNodes.Append(td);

// write text, no indent :(
using(StreamWriter sw = new StreamWriter("table.html"))
{
        table.WriteTo(sw);
}

// write xml, nicely indented but it's XML!
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Indent = true;
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlWriter xw = XmlTextWriter.Create("table.xml", settings))
{
        table.WriteTo(xw);
}

Ответы [ 4 ]

6 голосов
/ 11 мая 2011

Нет, и это выбор «по замыслу».Существует большая разница между XML (или XHTML, то есть XML, а не HTML), где - в большинстве случаев - пробелы не имеют особого значения, и HTML.

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

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

3 голосов
/ 08 марта 2019

Быстрый, надежный, чистый C #, совместимый с .NET Core AngleSharp

Вы можете разобрать его с помощью AngleSharp который предоставляет способ автоматического отступа:

var parser = new HtmlParser();
var document = parser.ParseDocument(text);
using (var writer = new StringWriter())
{
    document.ToHtml(writer, new PrettyMarkupFormatter
                            {
                                Indentation = "\t",
                                NewLine = "\n"
                            });
    var indentedText = writer.ToString();
}
3 голосов
/ 10 мая 2011

Насколько я знаю, HtmlAgilityPack не может этого сделать. Но вы можете просмотреть html аккуратные пакеты, которые предлагаются в похожих вопросах:

2 голосов
/ 18 июля 2015

Я сделал то же самое, хотя HtmlAgilityPack отлично подходит для чтения и изменения файлов Html (или в моем случае asp), которые вы не можете создать для чтения.

Однако в итоге я написал несколько строк кода, которые работают для меня:

Имея HtmlDocument с именем "m_htmlDocument", я создаю свой HTML-файл следующим образом:

file = new System.IO.StreamWriter(_sFullPath);
            if (m_htmlDocument.DocumentNode != null)
                foreach (var node in m_htmlDocument.DocumentNode.ChildNodes)
                    WriteNode(file, node, 0);

и

void WriteNode(System.IO.StreamWriter _file, HtmlNode _node, int _indentLevel)
    {
        // check parameter
        if (_file == null) return;
        if (_node == null) return;

        // init 
        string INDENT = " ";
        string NEW_LINE = System.Environment.NewLine;

        // case: no children
        if(_node.HasChildNodes == false)
        {
            for (int i = 0; i < _indentLevel; i++)
                _file.Write(INDENT);
            _file.Write(_node.OuterHtml);
            _file.Write(NEW_LINE);
        }

        // case: node has childs
        else
        {
            // indent
            for (int i = 0; i < _indentLevel; i++)
                _file.Write(INDENT);

            // open tag
            _file.Write(string.Format("<{0} ",_node.Name));
            if(_node.HasAttributes)
                foreach(var attr in _node.Attributes)
                    _file.Write(string.Format("{0}=\"{1}\" ", attr.Name, attr.Value));
            _file.Write(string.Format(">{0}",NEW_LINE));

            // childs
            foreach(var chldNode in _node.ChildNodes)
                WriteNode(_file, chldNode, _indentLevel + 1);

            // close tag
            for (int i = 0; i < _indentLevel; i++)
                _file.Write(INDENT);
            _file.Write(string.Format("</{0}>{1}", _node.Name,NEW_LINE));
        }
    }
...