2012-12-19 9 views
6

は、私はたくさんの周りを見てきましたが、見つけることができませんでしたビルトイン特殊なXML文字エスケープします.NETメソッド: <>&'" をそうでない場合タグ。タグがエスケープされていないことを条件付きで脱出特殊なXML文字

Test&amp; <b>bold</b> <i>italic</i> &lt;<Tag index="0" /> 

お知らせ:

Test& <b>bold</b> <i>italic</i> <<Tag index="0" /> 

が、私はそれがに変換したい:

はたとえば、次のテキストを取ります。この値をXmlElementInnerXMLに設定する必要があり、その結果、これらのタグを保存する必要があります。

私は自分自身のパーサーを実装し、StringBuilderを使用してできる限り最適化しましたが、かなり厄介なことがあります。

私は、物事を簡素化する可能性のあるタグも知っています(br、b、i、u、blink、flash、Tag)。また、これらのタグは、自己終了タグ

(e.g. <u />) 

またはコンテナタグ

(e.g. <u>...</u>) 
+2

HTMLはXMLではありません...「foo bar本当に
'のようです。あなたは自分でそれをやりたいなら、たくさんの楽しみの中にいます。オプションとして、HtmlAgilityPackがHTMLを適切なツリーに解析し、注意深くXMLにすべてのノードを挿入することを検討してください。 –

+0

「Test Value is < 3 but > 1'」を正しく処理することはできません。 – Bobson

+0

@Bobson '<3'は有効な開始タグではないので、それを理解することができます。しかし、あなたのポイントはまだ立っていて、 '<' and '>'はエスケープされ、解析中のあいまいさを取り除きます。合理的なパーサーが1つのパスを選択するケースがありますが、別のパスを希望しているかもしれません。 – climbage

答えて

2

注:これはおそらく最適化されている可能性があります。それは私があなたのためにすぐにノックしたものでした。また、タグ自体の検証も行っていないことに注意してください。それは山括弧で囲まれた内容を探しているだけです。また、タグ内に角括弧(たとえば、<sometag label="I put an > here">)が見つかった場合は失敗します。それ以外は、あなたが求めていることをすべきだと思います。

namespace ConsoleApplication1 
{ 
    using System; 
    using System.Text.RegularExpressions; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      // This is the test string. 
      const string testString = "Test& <b>bold</b> <i>italic</i> <<Tag index=\"0\" />"; 

      // Do a regular expression search and replace. We're looking for a complete tag (which will be ignored) or 
      // a character that needs escaping. 
      string result = Regex.Replace(testString, @"(?'Tag'\<{1}[^\>\<]*[\>]{1})|(?'Ampy'\&[A-Za-z0-9]+;)|(?'Special'[\<\>\""\'\&])", (match) => 
       { 
        // If a special (escapable) character was found, replace it. 
        if (match.Groups["Special"].Success) 
        { 
         switch (match.Groups["Special"].Value) 
         { 
          case "<": 
           return "&lt;"; 
          case ">": 
           return "&gt;"; 
          case "\"": 
           return "&quot;"; 
          case "\'": 
           return "&apos;"; 
          case "&": 
           return "&amp;"; 
          default: 
           return match.Groups["Special"].Value; 
         } 
        } 

        // Otherwise, just return what was found. 
        return match.Value; 
       }); 

      // Show the result. 
      Console.WriteLine("Test String: " + testString); 
      Console.WriteLine("Result  : " + result); 
      Console.ReadKey(); 
     } 
    } 
} 
+0

有効なHTMLが破損します。たとえば、 '&'を '& amp;'に変換します。 –

+0

Fine。修正しました。 –

+0

@NigelWhatling非常に良い、よくできました!唯一の欠点は、サポートされていないタグがエスケープされないことです(はエスケープされません)。 – Amir

2

することができ、私は個人的にあなたが本当に不正なHTMLを修正しようとしているので、そこにされているので、それが可能だとは思いません何がエンコードされ、何がエンコードされないのかを判断するためのルールはありません。

どのように見ても、<<Tag index="0" />のようなものは有効なHTMLではありません。

実際のタグを知っていれば、簡単なものにすることができるホワイトリストを作成できますが、より具体的にあなたの問題を攻撃する必要があります。どのシナリオでもこれを解決することはできません。

実際には、<または>のランダムな文字はテキストにはないので、問題が大幅に簡素化されますが、実際にはジェネリックソリューションを考えようとしている....私はあなたの幸運を祈ります。

+0

彼は既にごくわずかな有効なタグのセットを許可していることを除いて、それは可能ではありません。 – Bobson

1

は、ここでは、それが無効な<または>一致します使用することができ、正規表現です。

(\<(?! ?/?(?:b|i|br|u|blink|flash|Tag[^>]*))|(?<! ?/?(?:b|i|br|u|blink|flash|Tag[^>]*))\>) 

私は有効なタグテスト式を変数に入れ、その周りに残りを構築することをお勧めします。

var validTags = "b|i|br|u|blink|flash|Tag[^>]*"; 
var startTag = @"\<(?! ?/?(?:" + validTags + "))"; 
var endTag = @"(?<! ?/?(?:" + validTags + "))/>"; 

次に、RegEx.Replaceを実行してください。