2012-06-16 1 views
0

Вот код:htmlagilitypack странное поведение при использовании 2 HTMLDocument объектов

HtmlDocument htmlDoc = new HtmlDocument(); 
HtmlDocument segment = new HtmlDocument(); 

htmlDoc.OptionWriteEmptyNodes = true; 
segment.OptionWriteEmptyNodes = true;    

htmlDoc.Load("sourcepath"); 
segment.Load("sourcepath"); 

//Fix HtmlAgilityPack bug with ending tag at xmldeclaration 
var newNodeStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 
var newNode = HtmlNode.CreateNode(newNodeStr); 
htmlDoc.DocumentNode.ReplaceChild(newNode, htmlDoc.DocumentNode.FirstChild); 
segment.DocumentNode.ReplaceChild(newNode, segment.DocumentNode.FirstChild);  

HtmlNode sbodyNode = segment.DocumentNode.SelectSingleNode("//body"); 
if (sbodyNode != null) 
sbodyNode.RemoveAllChildren(); 

HtmlNode bodyNode = htmlDoc.DocumentNode.SelectSingleNode("//body"); 
int numberOfChilds = bodyNode.ChildNodes.Count; 
MessageBox.Show(numberOfChilds.ToString()); 

segment.Save("destpath1", Encoding.UTF8); 
htmlDoc.Save("destpath2", Encoding.UTF8); 

Ввод просто XHTML. Я хочу изменить файл xhtml (это представлен htmlDoc). Для этого я создал еще один объект HtmlDocument (сегмент, загрузите в него один и тот же xhtml). В качестве первого шага я пытаюсь удалить все дочерние элементы тела. Затем я добавлю некоторые элементы обратно с помощью htmlDoc obeject. Проблема с вышеизложенным заключается в том, что удаление этих сегментов также влияет на htmlDoc (другой объект). Поэтому MessageBox всегда будет показывать 0. Вдобавок к этому, если я посмотрю на выходы, которые создаются с помощью функций Save, htmlDoc будет иметь элементы под ним, что будет означать, что MessageBox должен показать их количество (насколько я предполагаю). (Примечание: если я раскомментирую строку RemoveAllChildren(), а MessageBox показывает правильный номер.) Я думаю, что это некоторые тривиальные вещи, но для меня это странно странно. Спасибо за вашу помощь.

Обновление: Извините, я не опубликовал полный код beacuse. Я думал, что некоторые строки не имеют значения, но похоже, что это не так. Если я прокомментирую эти 4 строки после Loads, я получаю правильные цифры, и это работает, как и ожидалось. Вопрос в том, почему эти строки «вредят». (эти строки я написал, чтобы исправить выход, потому что agilitypack сделал заголовок заголовка xml /> вместо?>)

+0

Я не могу воспроизвести это с помощью вашего точного кода. Я получаю 6 childnodes (с моим примером html-файла). Отладчик показывает 0 дочерних узлов для другого sbodyNode.ChildNodes.Count. – jessehouwing

+0

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

+0

http://stackoverflow.com/a/15992718/3137362 Настоящая проблема описана здесь –

ответ

0

Ниже решается моя проблема, но не знаю, почему. Если кто-нибудь позаботится объяснить, я был бы бод.

var newNodeStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 
var newNode = HtmlNode.CreateNode(newNodeStr); 
var newNode2 = HtmlNode.CreateNode(newNodeStr); 
htmlDoc.DocumentNode.ReplaceChild(newNode, htmlDoc.DocumentNode.FirstChild); 
segment.DocumentNode.ReplaceChild(newNode2, segment.DocumentNode.FirstChild); 
0

Это на самом деле вполне логично. ReplaceChild не клонирует дочерний узел, он просто вставляет ссылку. Поэтому, если вы вызовете ClearChildNodes() на нем, он будет очищен во всех документах, где была добавлена ​​ссылка. Похоже, что HtmlNode реализует CloneNode, CopyTo и Clone. Один из этих методов следует вызвать, чтобы вставить копию вашего узла в каждый документ.

var newNodeStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 
var newNode = HtmlNode.CreateNode(newNodeStr); 

htmlDoc.DocumentNode.ReplaceChild(newNode.CloneNode(true), htmlDoc.DocumentNode.FirstChild); 
segment.DocumentNode.ReplaceChild(newNode.CloneNode(true), segment.DocumentNode.FirstChild); 
0

HtmlAgilityPack имеет ошибку, когда вы добавляете или удаления или замены элементов, когда вы используете «смотреть» и отладке ... чтобы исправить это странное поведение, очистить список часов в режиме отладки .. .