2009-04-17 21 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

この問題の1つの問題は、制動されていないスペースのように以前にエンコードされたエンティティがエンコードされることです。これは望ましくない動作です。 – MJJames

19

ユチョンが作品を示唆するように、出力XMLにそれを告げるが、あなたはXMLを希望しない他の理由がある場合は、これを試してみてください。

doc.OptionWriteEmptyNodes = true; 
1

これはHtmlAgilityPackのバグのようです。

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

出力不正な形式のHTML:例えば、これを再現する多くの方法があります。他の回答に示唆されている修正を使用しても何も起こりません。

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); 

編集1のような<x><img id="bla"></x>

I have created a issue in CodePlex for this.

+1

この問題はまだ存在し、 2010年からかなりの金額で、私はすぐにこれが修正されることに気づいていません。 – Nenotlep

+0

私はHAPを解析することを推奨しますが、既存のHTMLを変更することは推奨しません。 –

2

を不正な形式のXML/XHTMLを生成します:ここでは、正しくイメージ(IMG)タグを表示するHTML Agiltyパックの文書を修正する方法である:

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

他のタグでも「img」を置き換えてください(入力、選択、オプションが頻繁に表示されます)。必要に応じて繰り返します。これは、HAPバグが「クローズド」フラグと「空」フラグを同時に設定することを妨げるためではなく、むしろ生成されることに注意してください。 出典: はちょうどこの問題へのソリューションに比べて労働し、そして任意の十分な回答を見つけることではない(XMLとして出力を使用して適切に設定DOCTYPEを、構文をチェックし、AutoCloseOnEnd、そして空のノードのオプションを書く)を有する:http://htmlagilitypack.codeplex.com/discussions/53782

オリジナルの答えでMikeBridge 、私は汚れたハックでこれを解決することができました。 これは確か誰もが問題を解決するわけではありませんが、生成されたhtml/xmlを文字列(Webサービス経由のEG)として返す人にとって、簡単な解決策は、敏捷性パックが分からない偽のタグを使用することです。 文書で行う必要があることがすべて終わったら、頭痛を与えるタグごとに次のメソッドを1回呼び出します(注目すべき例は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の答え永久にどこよりも上にある。