2012-06-16 2 views
0

오브젝트 코드입니다 :htmlagilitypack 이상한 행동은 여기서

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을로드)를 만들었습니다. 첫 번째 단계로 body 요소의 모든 자식을 제거하려고합니다. 그런 다음 htmlDoc obeject를 사용하여 일부 요소를 다시 추가합니다. 위의 문제는 세그먼트에서 제거하면 htmlDoc (다른 객체)에도 영향을 미친다는 것입니다. 따라서 MessageBox는 항상 0을 표시합니다. 여기에 Save 함수에 의해 생성 된 결과물을 보면, htmlDoc은 the 아래의 엘리먼트를 가지게되어, MessageBox가 그 숫자를 보여 주어야한다는 것을 의미합니다. (참고 : If RemoveAllChildren() 줄의 주석 처리를 제거한 다음 MessageBox에 올바른 번호가 표시됩니다. 나는 그 사소한 것들을 생각하지만 저에게는 다소 이상합니다. 당신의 도움을 주셔서 감사합니다.

업데이트 : 죄송합니다. 전체 코드를 게시하지 않았으므로 일부 줄이 부적절하다고 생각되지만 모양이 맞지 않습니다. 로드 후 4 줄을 주석으로 처리하면 올바른 숫자가 표시되고 예상대로 작동합니다. 문제는 그 라인이 "해를 끼치는"이유입니다. (이 라인들은 출력을 고치기 위해 썼다. 왜냐하면 agilitypack이 xml 헤더를 닫는 태그를 만들었 기 때문이다.)>

+0

정확한 코드로 재생산 할 수 없습니다. 나는 6 개의 childnodes (예제 HTML 파일)를 얻었고 디버거는 다른 sbodyNode.ChildNodes.Count에 0 개의 자식 노드를 보여준다. – 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 당신이 추가 또는 삭제하거나 "볼"사용하고 디버깅 할 때 ...이 이상한 행동을 수정 디버그 모드에서 시계 목록을 지우려면 요소를 교체하는 버그가 있습니다 ..