2009-04-17 5 views
9

HTMLAgilityPack을 사용하여 새 이미지 노드를 작성하면 이미지의 닫는 태그 (예 : 해야한다 그러나 당신이 외부 html를 검사 할 때,있다.HTMLAgilityPack으로 이미지 태그가 닫히지 않습니다.

string strIMG = "<img src='" + imgPath + "' height='" + pubImg.Height + "px' width='" + pubImg.Width + "px' />"; 

HtmlNode newNode = HtmlNode.Create(strIMG); 

이 부분은 xhtml입니다.

답변

2

XML 출력을 켜서이 문제를 해결할 수있는 옵션이 있습니다.

var htmlDoc = new HtmlDocument(); 
htmlDoc.OptionOutputAsXml = true; 
htmlDoc.LoadHtml(rawHtml); 
+2

브레이크가 걸리지 않은 공간과 같이 이전에 인코딩 된 엔티티가 인코딩되면이 동작이 인코딩되지 않을 수 있습니다. 이것은 원치 않는 동작 일 수 있습니다. – MJJames

19

미키가 작품에서 알 수 있듯이 출력 XML로 말하는하지만 XML을하려는되지 않은 다른 이유가있을 경우,이 시도 :

doc.OptionWriteEmptyNodes = true; 
1

이 HtmlAgilityPack 버그 것 같다.

Debug.WriteLine(HtmlNode.CreateNode("<img id=\"bla\"></img>").OuterHtml); 

출력 잘못된 HTML : 예를 들어,이 문제를 재현하는 방법에는 여러 가지가 있습니다. 다른 답변에서 제안 된 수정 사항을 사용하면 아무런 효과가 없습니다. 여기에 제대로 이미지 (IMG) 태그를 표시하는 HTML Agilty 팩 문서를 수정하는 방법은 다음과 같습니다 :

HtmlDocument doc = new HtmlDocument(); 
doc.OptionOutputAsXml = true; 
HtmlNode node = doc.CreateElement("x"); 
node.InnerHtml = "<img id=\"bla\"></img>"; 
doc.DocumentNode.AppendChild(node); 
Debug.WriteLine(doc.DocumentNode.OuterHtml); 

<x><img id="bla"></x>

I have created a issue in CodePlex for this.

+1

이 문제는 여전히 존재하며 2007 년 초부터 트래커에 문제가 있다는 사실과 2010 년부터 상당한 액수의 돈을 벌어 들일 것입니다. – Nenotlep

+0

구문 분석에는 HAP을 권장하지만 기존 HTML은 수정하지 않는 것이 좋습니다. –

2

편집 한 것처럼 잘못된 XML/XHTML을 생성합니다

if (HtmlNode.ElementsFlags.ContainsKey("img")) 
{ HtmlNode.ElementsFlags["img"] = HtmlElementFlag.Closed;} 
else 
{ HtmlNode.ElementsFlags.Add("img", HtmlElementFlag.Closed);} 

"img"를 다른 태그로 바꾸면 입력, 선택 및 옵션이 자주 나타납니다. 필요에 따라 반복하십시오. HAP 버그로 인해 "닫힌"플래그와 "비어있는"플래그가 동시에 설정되는 것을 방지하기 때문에이 플래그가 생성됩니다. 출처 : MikeBridge http://htmlagilitypack.codeplex.com/discussions/53782

원래 답변에서 : 은이 문제에 대한 해결책을 이상 일한,하고 충분한 답변을 (문서 타입은 XML로 출력을 사용하여 적절하게 설정, 구문, AutoCloseOnEnd을 확인하고 빈 노드 옵션을 쓰기) 찾지 못하는 데 , 나는 더러운 해킹으로 이것을 해결할 수 있었다. 이것은 분명히 모든 사람에게 문제를 해결하지는 않지만 생성 된 html/xml을 문자열 (웹 서비스를 통해 EG)로 반환하는 사람들을 위해 간단한 해결책은 민첩성 팩이 알지 못하는 가짜 태그를 사용하는 것입니다 . 문서에서 수행해야하는 작업을 모두 마친 후에는 각 태그에 대해 두 번씩 다음과 같은 메소드를 호출하십시오 (주목할만한 예제는 option, input 및 img 임). 바로 직후에 최종 문자열을 렌더링하고 일부 문자열 (이 경우 "Fix_")이 붙은 각 태그에 대해 간단한 바꾸기를 수행하고 문자열을 반환하십시오. 이 내가 생각 것이다 베팅 사람이라면 나는 순간에 메모로

private void fixHAPUnclosedTags(ref HtmlDocument doc, string tagName, bool hasInnerText = false) 
{ 
    HtmlNode tagReplacement = null; 
    foreach(var tag in doc.DocumentNode.SelectNodes("//"+tagName) 
    { 
     tagReplacement = HtmlTextNode.CreateNode("<fix_"+tagName+"></fix_"+tagName+">"); 
     foreach(var attr in tag.Attributes) 
     { 
      tagReplacement.SetAttributeValue(attr.Name, attr.Value); 
     } 
     if(hasInnerText)//for option tags and other non-empty nodes, the next (text) node will be its inner HTML 
     { 
      tagReplacement.InnerHtml = tag.InnerHtml + tag.NextSibling.InnerHtml; 
      tag.NextSibling.Remove(); 
     } 
     tag.ParentNode.ReplaceChild(tagReplacement, tag); 
    } 
} 

(의 라인을 따라 뭔가를) 찾을 수없는 또 다른 질문에서 제안 된 정규식 솔루션보다 내 의견 만 변두리에 더 좋다 위의 MikeBridge의 대답은 실수로 팩에서이 버그의 원인을 식별합니다. 무엇인가가 닫혀 있고 비어있는 플래그를 상호 배타적으로 만듭니다.

또한 파고가 조금 더 지나서야 나는 유일한 사람으로 보이지 않습니다. 이 접근법을 취했습니다 :

비어 있지 않은 요소 만 필요로하는 경우에는 동일한 질문에 나열된 간단한 픽스와 여기에있는 HAP 코드 플렉스 토론이 있습니다. http://htmlagilitypack.codeplex.com/discussions/14982?ProjectName=htmlagilitypack 이것은 기본적으로 MikeBridge의 대답에 나열된 빈 플래그 옵션을 설정합니다 영구히 사방에.

관련 문제