2013-05-06 81 views
2

我目前在c#中編寫一個桌面應用程序,它也必須處理XHTML文檔操作。爲此,我使用的是Html Agility Pack,目前看起來沒問題。仔細檢查Html Agility Pack的輸出後,我發現代碼沒有正確的形成xhtml。HTML敏捷包(C#)malforms我的代碼

它消除自閉標籤(斜線),並覆蓋其他專有代碼元素...

如。 輸入HTML代碼

<input autocapitalize="off" id="username" name="username" placeholder="Benutzername" type="text" value="$(username)" /> 

如。 輸出HTML代碼

<input autocapitalize="off" id="username" name="username" placeholder="Benutzername" type="text" value="$(username)"> 

(除去最後的斜線...)

另一個例子是專有的代碼元素(的MikroTik熱點的設備):

例如輸入HTML代碼

<form action="$(link-login-only)" method="post" name="login" $(if chap-id) onSubmit="return doLogin()"$(endif)> 

The $(if chap-id)$(endif)$(link-login-only)部分是從Mikrotik器件解釋的自定義代碼片段。

例如。 輸出HTML代碼後的Html敏捷包(它轉變爲unuseable代碼)

<form action="$(link-login-only)" method="post" name="login" $(if="" chap-id)="" onsubmit="return doLogin()" $(endif)=""> 

有別人的想法如何「指導」的Html敏捷包輸出以及形成的XHTML,而忽略「定製代碼」片段(這可能是通過正則表達式)?

在此先感謝! :-)

+0

爲什麼不使用XML解析器,而不是HAP(這是一個HTML,而不是XHTML/XML解析器)?從codplex的項目頁面:「雖然您可以使用該工具實際生成XML,但也沒有遵守XHTML或XML。」 – Oded 2013-05-06 18:31:46

+0

你有沒有試過'htmlDocument.Save(XmlWriter);' – I4V 2013-05-06 18:33:23

+0

@ I4V我用''htmlDocument.Save()'' - 方法 – thedom 2013-05-06 18:49:19

回答

3

在您的第一個示例中,HTML Agility Pack實際上正在修復您的標記。輸入元素是void element。由於裏面沒有上下文,因此不需要結束標記。

HTML Agility Pack是用於解析有效的HTML標記,而不是嵌入自定義代碼的標記。在第一個示例中,自定義標記位於引號內,因此不是問題。在第二個例子中,變量在引號之外。

HTML Agility Pack嘗試將它們解析爲元素的常規(但格式錯誤)屬性。沒有辦法解決這個問題。如果您需要支持標記中的自定義代碼,則必須找到解析標記的另一種方法。

+0

任何想法如何實現?只要有任何方法可以讓我的「自定義標籤」保持不變,我就可以與「修復」標記一起生活......它不一定非得與HTML敏捷包一起使用。 – thedom 2013-05-06 18:47:52

+0

@Justin Niessner:「由於裏面沒有上下文,所以不需要結束標記。」:不正確。這取決於輸出格式是XHTML/XML還是HTML/SGML。在XHTML/XML的情況下需要它。但問題在於OP沒有定義輸出格式,因此HtmlAgilityPack使用了默認的(SGML)。 – 2017-09-28 14:19:48

+0

@Justin Niessner:斯特凡·斯泰格所說的,加上:只是一個元素(''div',說)沒有實際的內容,不*意味着可以省略結束元素標籤。在SGML中,只有那些被聲明爲具有'EMPTY'內容的元素(忽略'#CONREF'屬性和WebSGML/XML)*必須沒有末尾元素標籤,例如HTML鏈接''hr','br' ,'img'等元素。但是,例如。 'script'元素,即使與'href'屬性一起使用,並且沒有文字腳本子內容,*必須*有一個結束元素標記。看到http://sgmljs.net/docs/w3c-html51-dtd.html我的HTML 5.1 DTD參考 – imhotap 2017-09-28 16:45:33

0

另一種方法是CsQuery,至少對於你在這裏得到的簡單情況,只會將你的預處理器標籤僅僅視爲無價值的屬性。也就是說,HAP似乎將沒有值的任何屬性someattribute轉換爲someattribute=""。 CsQuery不會這樣做。

然而,@Justin Niessner關於您的標記的觀察結果對於任何不是專門設計用於解析您在其中的模板代碼的解析器都是正確的。僅僅因爲這個例子通過CsQuery實現它並不能保證其他一些格式不會導致某些不是有效的屬性名稱,或者如果無效,至少可以被HTML5解析器接受。

如果您需要處理的東西作爲HTML,然後再去做模板後。如果你需要在之前操作模板引擎,那麼你在catch 22中,因爲它還不是HTML。或者,您也可以使用爲其關鍵字使用有效HTML標記的模板系統(例如:Knockout)。

1

Necromancing。
問題1是因爲你可能沒有指定OptionOutputAsXml = true,意味着HtmlAgilityPack輸出HTML而不是XHTML。

其實,這樣做是相當聰明的,因爲它減少了文件大小。
如果您需要XHTML,您需要特別指示HtmlAgilityPack輸出XHTML(XML),而不是HTML(SGML)。

SGML允許沒有結束標記(/>)標籤,而XML沒有。
爲了解決這個問題:

public static void BeautifyHtml() 
{ 
    string input = "<html><body><p>This is some test test<br ><ul><li>item 1<li>item2<</ul></body>"; 

    HtmlAgilityPack.HtmlDocument test = new HtmlAgilityPack.HtmlDocument(); 
    test.LoadHtml(input); 
    test.OptionOutputAsXml = true; 
    test.OptionCheckSyntax = true; 
    test.OptionFixNestedTags = true; 


    System.Text.StringBuilder sb = new System.Text.StringBuilder(); 
    using (System.IO.TextWriter stringWriter = new System.IO.StringWriter(sb)) 
    { 
     test.Save(stringWriter); 
    } 

    string beautified = sb.ToString(); 
    System.Console.WriteLine(beautified); 
}