2013-07-12 39 views
0

我有一個很大的htmlencoded字符串,我只想解碼特定的白名單html標籤。C#HtmlDecode僅限特定標籤

有沒有辦法在c#中做到這一點,WebUtility.HtmlDecode()解碼的一切。

`我正在尋找一個DecodeSpecificTags()的實現,它將通過下面的測試。

[Test] 
    public void DecodeSpecificTags_SimpleInput_True() 
    { 
     string input = "<span>i am <strong color=blue>very</strong> big <br>man.</span>"; 
     string output = "&lt;span&gt;i am <strong color=blue>very</strong> big <br>man.&lt;/span&gt;"; 
     List<string> whiteList = new List<string>(){ "strong","br" } ; 

     Assert.IsTrue(DecodeSpecificTags(whiteList,input) == output); 
    }` 
+0

你想達到什麼目的?可能還有另一種更好的方式。你也可以做的是獲取需要解碼的文本的子串,然後在解碼之後附加剩餘的編碼文本。 –

回答

1

一個更好的辦法可能是使用一些HTML解析器像Agilitypack或csquery或Nsoup找到特定的元素,它在一個循環中進行解碼。

check this for links and examples of parsers

檢查它,我做到了使用csquery:

string input = "&lt;span&gt;i am &lt;strong color=blue&gt;very&lt;/strong&gt; big &lt;br&gt;man.&lt;/span&gt;"; 
string output = "&lt;span&gt;i am <strong color=blue>very</strong> big <br>man.&lt;/span&gt;"; 

var decoded = HttpUtility.HtmlDecode(output); 
var encoded =input ; // HttpUtility.HtmlEncode(decoded); 

Console.WriteLine(encoded); 
Console.WriteLine(decoded); 

var doc=CsQuery.CQ.CreateDocument(decoded); 

var paras=doc.Select("strong").Union(doc.Select ("br")) ; 

var tags=new List<KeyValuePair<string, string>>(); 
var counter=0; 

foreach (var element in paras) 
{ 
    HttpUtility.HtmlEncode(element.OuterHTML).Dump(); 
    var key ="---" + counter + "---"; 
    var value= HttpUtility.HtmlDecode(element.OuterHTML); 
    var pair= new KeyValuePair<String,String>(key,value); 

    element.OuterHTML = key ; 
    tags.Add(pair); 
    counter++; 
} 

var finalstring= HttpUtility.HtmlEncode(doc.Document.Body.InnerHTML); 
finalstring.Dump(); 

foreach (var element in tags) 
{ 
finalstring=finalstring.Replace(element.Key,element.Value); 
} 

Console.WriteLine(finalstring); 
+0

我可能會缺少HtmlAgility的一些功能,但我不確定這將工作,如果輸入不是HTML(因爲它已被編碼)? – PeteN

+1

@PeteN - 你可以HtmlDecode整個字符串,然後訪問每個元素,如果它不在你的白名單中,重新編碼它。 –

1

你可以做這樣的事情

public string DecodeSpecificTags(List<string> whiteListedTagNames,string encodedInput) 
{ 
    String regex=""; 
    foreach(string s in whiteListedTagNames) 
    { 
     regex="&lt;"[email protected]"\s*/?\s*"+s+".*?"+"&gt;"; 
     encodedInput=Regex.Replace(encodedInput,regex); 
    } 
    return encodedInput; 
} 
+0

+1如何解決問題。 @PeteN完美,所以你有了解如何解決它的想法。你只需修改正則表達式以適合你的特定用例。 –

+0

@PeteN編輯應該解決問題 – Anirudha

+0

@winner_joiner是解決方案的+1,老實說,雖然我確實得到了那麼多我自己,這正是我正在努力的正則表達式部分:) – PeteN

0

或者你可以使用HtmlAgility與黑名單或白名單根據您的要求。我正在使用黑名單方法。 我的黑名單標籤存儲在一個文本文件中,例如「script | img」

public static string DecodeSpecificTags(this string content, List<string> blackListedTags) 
    { 
     if (string.IsNullOrEmpty(content)) 
     { 
      return content; 
     } 
     blackListedTags = blackListedTags.Select(t => t.ToLowerInvariant()).ToList(); 
     var decodedContent = HttpUtility.HtmlDecode(content); 
     var document = new HtmlDocument(); 
     document.LoadHtml(decodedContent); 
     decodedContent = blackListedTags.Select(blackListedTag => document.DocumentNode.Descendants(blackListedTag)) 
       .Aggregate(decodedContent, 
        (current1, nodes) => 
         nodes.Select(htmlNode => htmlNode.WriteTo()) 
          .Aggregate(current1, 
           (current, nodeContent) => 
            current.Replace(nodeContent, HttpUtility.HtmlEncode(nodeContent)))); 
     return decodedContent; 
    }