2016-06-30 36 views
0

XmlSerializerを使用して、class.xmlファイルに出力しています。ほとんどの場合、これは期待どおりに動作しています。しかし、要件として、特定の文字をデータの値から削除し、適切なエスケープ文字に置き換える必要があります。追加されたエスケープ文字をエスケープするXmlSerializer

値を置き換える必要がある要素では、Replace()メソッドを使用して、更新された文字列を返します。下のコードはこの文字列置換を示しています。コメントされた行は、XmlSerializerがすでにその特定の文字をエスケープしているためです。

私は、彼らはXML要素の値の範囲内に表示されたときに&<>'、および"文字をエスケープするには、サードパーティからの要求を持っています。現在、&<、および>の文字は、XmlSerializerで適切にエスケープされています。これらの文字が存在する場合

エラーが受信される。

我々のシステムは、要求メッセージの添付ファイル内の潜在的な脅威を検出しました。

私は、文字列の置き換え行った後、XMLドキュメントをシリアル化するときしかし、XmlSerializer&apos;&文字を見て、それ&amp;apos;ます。私はこれがXmlSerializerオブジェクトの正しい機能だと思います。しかし、私はシリアライザをにしたいと思います。はエスケープ文字を無視します。またはb)は、エスケープするために必要な他の文字をシリアル化します。

誰かが、具体的にどのようにこれらのいずれかを達成するためにいくつかの光を当てることができますか?

文字列置換法

public static string CheckValueOfProperty(string str) 
{ 
    string trimmedString = str.Trim(); 

    if (string.IsNullOrEmpty(trimmedString)) 
     return null; 
    else 
    { 
     // Commented out because the Serializer already transforms a '&' character into the appropriate escape character. 
     //trimmedString = trimmedString .Replace("&", "&amp;"); 
     //trimmedString = trimmedString.Replace("<", "&lt;"); 
     //trimmedString = trimmedString.Replace(">", "&gt;"); 

     trimmedString = trimmedString.Replace("'", "&apos;"); 
     trimmedString = trimmedString.Replace("\"", "&quot;"); 

     return trimmedString; 
    } 
} 

のXmlSerializerコード

public static void SerializeAndOutput(object obj, string outputFilePath, XmlSerializerNamespaces ns = null) 
{ 
    XmlSerializer x = new XmlSerializer(obj.GetType()); 

    // If the Output File already exists, delete it. 
    if (File.Exists(outputFilePath)) 
    { 
     File.Delete(outputFilePath); 
    } 

    // Then, Create the Output File and Serialize the parameterized object as Xml to the Output File 
    using (TextWriter tw = File.CreateText(outputFilePath)) 
    { 
     if (ns == null) 
     { 
      x.Serialize(tw, obj); 
     } 
     else { x.Serialize(tw, obj, ns); } 
    } 

    // ===================================================================== 
    // The code below here is no longer needed, was used to force "utf-8" to 
    // UTF-8" to ensure the result was what was being expected. 
    // ===================================================================== 
    // Create a new XmlDocument object, and load the contents of the OutputFile into the XmlDocument 
    // XmlDocument xdoc = new XmlDocument() { PreserveWhitespace = true }; 
    // xdoc.Load(outputFilePath); 

    // Set the Encoding property of each XmlDeclaration in the document to "UTF-8"; 
    // xdoc.ChildNodes.OfType<XmlDeclaration>().ToList().ForEach(d => d.Encoding = "UTF-8"); 

    // Save the XmlDocument to the Output File Path. 
    // xdoc.Save(outputFilePath); 
} 

答えて

0

XML内のノードのコンテンツ内で使用する場合、単一および二重引用符文字をエスケープする必要はありません。一重引用符または二重引用符は、ノード属性の値で使用する場合にのみエスケープする必要があります。そのため、XMLSerializerはエスケープしません。また、あなたはそれらを逃れる必要もありません。

参照のためthis question and answerを参照してください。


BTW:エンコーディングをUTF-8に設定する方法は、やっかいです。 StreamWriterでエンコーディングを指定すると、XMLSerializerはそのエンコーディングを自動的に使用し、XML宣言でそのエンコーディングを指定します。

+0

ただし、XML要素の実際の値の一部である場合、それらをエスケープする必要があります。これは要件です。 'XmlSerializer'は、値として現れたとき、自動的に'& '、'> '、' <'をエスケープしています。私はまた、一重引用符と二重引用符から逃げる必要があります。 – Russ

+0

あなたの要件はどこから来ましたか? XML標準の要件ではありません。 – NineBerry

+0

XMLを受け入れる第三者の要件です。彼らはこれらの文字をエスケープする必要があります。 – Russ

0

ここに私が思いついた解決策があります。サンプルXMLファイルでテストしただけで、作成している実際のXMLファイルではないため、パフォーマンスが低下する可能性があります。しかし、これは動作しているようです。

XMLファイルを文字列として読み込み、文字列にある定義済みの「特殊」文字を適切なエスケープ文字に置き換えます。 specialCharacterListDictionary<string, string>の順に処理する必要があります。つまり、&文字を最初に処理する必要があります。 <,>および"の文字を処理する場合、XML要素の値のみを調べます。

using System; 
using System.Collections.Generic; 
using System.IO; 

namespace testSerializer 
{ 
    class Program 
    { 
     private static string filePath = AppDomain.CurrentDomain.BaseDirectory + "testFile.xml"; 
     private static string tempFile = AppDomain.CurrentDomain.BaseDirectory + "tempFile.xml"; 

     private static Dictionary<string, string> specialCharacterList = new Dictionary<string, string>() 
     { 
      {"&","&amp;"}, {"<","&lt;"}, {">","&gt;"}, {"'","&apos;"}, {"\"","&quot;"} 
     }; 

     static void Main(string[] args) 
     { 
      ReplaceSpecialCharacters(); 
     } 

     private static void ReplaceSpecialCharacters() 
     { 
      string[] allLines = File.ReadAllLines(filePath); 

      using (TextWriter tw = File.CreateText(tempFile)) 
      { 
       foreach (string strLine in allLines) 
       { 
        string newLineString = ""; 
        string originalString = strLine; 

        foreach (var item in specialCharacterList) 
        { 
         // Since these characters are all valid characters to be present in the XML, 
         // We need to look specifically within the VALUE of the XML Element. 
         if (item.Key == "\"" || item.Key == "<" || item.Key == ">") 
         { 
          // Find the ending character of the beginning XML tag. 
          int firstIndexOfCloseBracket = originalString.IndexOf('>'); 

          // Find the beginning character of the ending XML tag. 
          int lastIndexOfOpenBracket = originalString.LastIndexOf('<'); 

          if (lastIndexOfOpenBracket > firstIndexOfCloseBracket) 
          { 
           // Determine the length of the string between the XML tags. 
           int lengthOfStringBetweenBrackets = lastIndexOfOpenBracket - firstIndexOfCloseBracket; 

           // Retrieve the string that is between the element tags. 
           string valueOfElement = originalString.Substring(firstIndexOfCloseBracket + 1, lengthOfStringBetweenBrackets - 1); 

           newLineString = originalString.Substring(0, firstIndexOfCloseBracket + 1) + valueOfElement.Replace(item.Key, item.Value) + originalString.Substring(lastIndexOfOpenBracket); 
          } 
         } 
         // For the ampersand (&) and apostrophe (') characters, simply replace any found with the escape. 
         else 
         { 
          newLineString = originalString.Replace(item.Key, item.Value); 
         } 

         // Set the "original" string to the new version. 
         originalString = newLineString; 
        } 

        tw.WriteLine(newLineString); 
       } 
      } 
     } 
    } 
} 
関連する問題