C# Разметка HTML Разметка в XML
Я действительно надеюсь, что кто-то может помочь мне с этим вопросом. Решение должно быть на C#.
У меня есть XML-файл размером 36 МБ и 900k строк. На некоторых узлах есть много HTML-разметки и некоторые недопустимые разметки, такие как
<Obs><p>
<jantes -="" .="" 22.000="" apenas="" exclusive="" kms.="" leve="" liga="" o=""> </jantes></p>
Я пробовал разные способы очистки этого файла, но только один способ может выполнить задачу, однако, поскольку это выполняется в веб-приложении, оно блокирует приложение и занимает около 6 минут, чтобы завершить задачу, и потребляет около 450 МБ в объем памяти.
Поскольку этот файл является недействительным XML, я не могу использовать XmlTextReader. Использование XLST, основанное на вырезании HTML-подобных символов (не разметки) из XML с помощью XSLT? Странно, у меня тоже проблемы с HTML-сущностями.
Процесс, который работал (с некоторыми изменениями), следующий на http://www.codeproject.com/Articles/19652/HTML-Tag-Stripper
Спасибо
Редактировать:
Следуя советам Кевина. Я пытаюсь создать решение с использованием HTML Agility Pack. По крайней мере, сделать несколько тестов. Я застрял однако. Представьте себе следующий узел xml:
<Obs><p> I WANT THIS TEXT<jantes -="" .="" 22.000="" apenas="" exclusive="" kms.="" leve="" liga="" o=""> </jantes></p></Obs>
Как я могу удалить теги внутри тега "obs", оставить тег "obs", а также оставить текст "Я ХОЧУ ЭТОТ ТЕКСТ"? В основном это:
<Obs>I WANT THIS TEXT</Obs>
На данный момент это код, который у меня есть:
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(text);
Queue<HtmlNode> nodes = new Queue<HtmlNode>(doc.DocumentNode.SelectNodes("./*|./text()"));
while (nodes.Count > 0)
{
HtmlNode node = nodes.Dequeue();
HtmlNode parentNode = node.ParentNode;
HtmlNodeCollection childNodes = node.SelectNodes("./*|./text()");
if (childNodes != null)
{
foreach (HtmlNode child in childNodes)
{
if (child.Name != "obs")
{
nodes.Enqueue(child);
}
else
{
childNodes = child.SelectNodes("//p|//jantes");
foreach (HtmlNode nodeToStrip in childNodes)
nodeToStrip.ParentNode.RemoveChild(nodeToStrip);
}
}
}
}
string s = doc.DocumentNode.InnerHtml;
Спасибо:)
РЕДАКТИРОВАТЬ 2
Хорошо, я смог выполнить задачу. Однако это занимает слишком много времени. Около 3 часов и 800 МБ памяти.
Все еще нуждаюсь в помощи!
Вот код, это может кому-то помочь.
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(text);
Queue<HtmlNode> nodes = new Queue<HtmlNode>(doc.DocumentNode.SelectNodes("./*|./text()"));
while (nodes.Count > 0)
{
HtmlNode node = nodes.Dequeue();
HtmlNode parentNode = node.ParentNode;
HtmlNodeCollection childNodes = node.SelectNodes("./*|./text()");
if (childNodes != null)
{
foreach (HtmlNode child in childNodes)
{
if (child.Name != "obs")
{
nodes.Enqueue(child);
}
else
{
childNodes = child.SelectNodes("//p|//jantes");
if (childNodes != null)
{
foreach (HtmlNode nodeToStrip in childNodes)
{
var replacement = doc.CreateTextNode(nodeToStrip.InnerText);
nodeToStrip.ParentNode.ReplaceChild(replacement, nodeToStrip);
}
}
}
}
}
}
string s = doc.DocumentNode.InnerHtml;
1 ответ
Вы пробовали Html Agility Pack? Среди его претензий:
- синтаксический анализатор очень терпим с искаженным HTML "реального мира"
- Вы можете исправить страницу так, как вы хотите, изменить DOM, добавить узлы, скопировать узлы, ну... вы называете это