文字列をエスケープおよびエスケープ解除するために使用できるC#関数はありますか。XML要素のコンテンツを埋めるために使用できますか?
VSTS 2008 + C#+ .Net 3.0を使用しています。
編集1:単純な短いXMLファイルを連結しており、シリアル化を使用していないため、XML文字を手動で明示的にエスケープする必要があります。たとえば、にa<b
挿入<foo></foo>
する必要があるため、エスケープ文字列a<b
と要素fooに挿入する必要があります。
文字列をエスケープおよびエスケープ解除するために使用できるC#関数はありますか。XML要素のコンテンツを埋めるために使用できますか?
VSTS 2008 + C#+ .Net 3.0を使用しています。
編集1:単純な短いXMLファイルを連結しており、シリアル化を使用していないため、XML文字を手動で明示的にエスケープする必要があります。たとえば、にa<b
挿入<foo></foo>
する必要があるため、エスケープ文字列a<b
と要素fooに挿入する必要があります。
new XText(unescaped).ToString()
回答:
public static string XmlEscape(string unescaped)
{
XmlDocument doc = new XmlDocument();
XmlNode node = doc.CreateElement("root");
node.InnerText = unescaped;
return node.InnerXml;
}
public static string XmlUnescape(string escaped)
{
XmlDocument doc = new XmlDocument();
XmlNode node = doc.CreateElement("root");
node.InnerXml = escaped;
return node.InnerText;
}
HttpUtility.HtmlEncode
からSystem.Web
安心して使用されるだろうか?
編集:「単純で短いXMLファイルを連結しており、シリアル化を使用していないため、手動でXML文字を明示的にエスケープする必要がある」とあなたは言う。
手で行わないことを強くお勧めします。XML APIを使用してすべてを実行します-元のファイルを読み取り、2つを1つのドキュメントにマージしますが、必要に応じて(おそらく使用する必要がありますXmlDocument.ImportNode
)、それからもう一度書き出します。独自のXMLパーサー/フォーマッターを作成する必要はありません。シリアライゼーションはここでは多少関係ありません。
あなたが何をしようとしているのかを簡潔に示した完全な例を教えていただければ、そもそもエスケープについて心配する必要がないようにお手伝いできるでしょう。
元の答え
それが何を意味するのかは完全に明らかではありませんが、通常、XML APIがこれを行います。ノードにテキストを設定すると、必要なものはすべて自動的にエスケープされます。例えば:
LINQ to XMLの例:
using System;
using System.Xml.Linq;
class Test
{
static void Main()
{
XElement element = new XElement("tag",
"Brackets & stuff <>");
Console.WriteLine(element);
}
}
DOMの例:
using System;
using System.Xml;
class Test
{
static void Main()
{
XmlDocument doc = new XmlDocument();
XmlElement element = doc.CreateElement("tag");
element.InnerText = "Brackets & stuff <>";
Console.WriteLine(element.OuterXml);
}
}
両方の例からの出力:
<tag>Brackets & stuff <></tag>
もちろん、XMLエスケープが必要な場合を想定しています。そうでない場合は、詳細を投稿してください。
1行のエスケープについて@seheに感謝します。
var escaped = new System.Xml.Linq.XText(unescaped).ToString();
それに1行のエスケープ解除を追加します。
var unescapedAgain = System.Xml.XmlReader.Create(new StringReader("<r>" + escaped + "</r>")).ReadElementString();
ジョージ、それは簡単です。XMLの処理には、常にXML APIを使用してください。彼らはあなたのためにすべてのエスケープとアンエスケープを行います。
文字列を追加してXMLを作成しないでください。
XmlElementSyntax
です。また、生成する必要があるという事実も複雑です///
。また、各行を個別のとして生成することはできませんXObject
。これは、複数行タグでは機能しないためです。
///
前に貼り付けてから、コードを再フォーマットします。大したことではなく、確かに非常にまれなケースです。どうしても必要な場合XmlWriter
は、改行と空白を希望どおりに作成し、///
新しい行の前に配置するカスタムを作成できると思います。または、XSLTを使用してXMLをきれいに出力します。ただし、いずれの場合でも、XMLはXML APIによって生成されます。
そして、私がこの質問を見つけたときのように、たとえばXMLシリアル化から読み取るときなど、XMLノード名をエスケープするには、最も簡単な方法を使用します。
XmlConvert.EncodeName(string nameToEscape)
また、スペースやXML要素の無効な文字をエスケープします。
http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape%28VS.80%29.aspx
警告:ネクロマンシング
それでもDarin Dimitrovの回答+ System.Security.SecurityElement.Escape(string s)は完全ではありません。
XML 1.1では、最も簡単で安全な方法は、すべてをエンコードすることです。
同様に	
、\ tに対して。
XML 1.0ではまったくサポートされていません。
XML 1.0の場合、考えられる回避策の1つは、文字を含むテキストをbase-64エンコードすることです。
//string EncodedXml = SpecialXmlEscape("привет мир");
//Console.WriteLine(EncodedXml);
//string DecodedXml = XmlUnescape(EncodedXml);
//Console.WriteLine(DecodedXml);
public static string SpecialXmlEscape(string input)
{
//string content = System.Xml.XmlConvert.EncodeName("\t");
//string content = System.Security.SecurityElement.Escape("\t");
//string strDelimiter = System.Web.HttpUtility.HtmlEncode("\t"); // XmlEscape("\t"); //XmlDecode("	");
//strDelimiter = XmlUnescape(";");
//Console.WriteLine(strDelimiter);
//Console.WriteLine(string.Format("&#{0};", (int)';'));
//Console.WriteLine(System.Text.Encoding.ASCII.HeaderName);
//Console.WriteLine(System.Text.Encoding.UTF8.HeaderName);
string strXmlText = "";
if (string.IsNullOrEmpty(input))
return input;
System.Text.StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.Length; ++i)
{
sb.AppendFormat("&#{0};", (int)input[i]);
}
strXmlText = sb.ToString();
sb.Clear();
sb = null;
return strXmlText;
} // End Function SpecialXmlEscape
XML 1.0:
public static string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
public static string Base64Decode(string base64EncodedData)
{
var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}
次の関数が作業を行います。XmlDocumentに対してテストしませんでしたが、これははるかに速いと思います。
public static string XmlEncode(string value)
{
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
{
ConformanceLevel = System.Xml.ConformanceLevel.Fragment
};
StringBuilder builder = new StringBuilder();
using (var writer = System.Xml.XmlWriter.Create(builder, settings))
{
writer.WriteString(value);
}
return builder.ToString();
}
public static string XmlDecode(string xmlEncodedValue)
{
System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings
{
ConformanceLevel = System.Xml.ConformanceLevel.Fragment
};
using (var stringReader = new System.IO.StringReader(xmlEncodedValue))
{
using (var xmlReader = System.Xml.XmlReader.Create(stringReader, settings))
{
xmlReader.Read();
return xmlReader.Value;
}
}
}
代わりにサードパーティのライブラリ(Newtonsoft.Json)を使用する:
public static string XmlEncode(string unescaped)
{
if (unescaped == null) return null;
return JsonConvert.SerializeObject(unescaped); ;
}
public static string XmlDecode(string escaped)
{
if (escaped == null) return null;
return JsonConvert.DeserializeObject(escaped, typeof(string)).ToString();
}
例:
a<b
<==> "a<b"
<foo></foo>
<==> "foo></foo>"