エンティティは、技術的にはXMLの「数値参照」と呼ばれ、元のドキュメントがXDocument
に読み込まれると解決されます。 XDocument
がロードされた後に解決された空白のエンティティと、わずかな空白(通常はプレーンテキストのビューアのXMLドキュメントの書式設定に使用される)とを区別する方法がないため、問題を解決するには問題があります。したがって、あなたの文書に余分な空白がない場合にのみ以下が適用されます。
System.Xml
ライブラリでは、クラスのNewLineHandling
プロパティをEntitize
に設定することで、空白のエンティティを維持することができます。しかし、テキストノード内では、\r
から
までとなり、\n
から

にはなりません。
最も簡単な解決策は、XmlWriter
クラスから派生し、そのWriteString
メソッドをオーバーライドして、手動で空白文字を数字のエンティティに置き換えることです。 WriteString
方法はまた、.NETは、それぞれ&
、<
、及び>
にエンティティ化された構文マーカー&
、<
、及び>
、テキスト・ノードに表示される許可されていない文字をentitizes場所であることを起こります。
XmlWriter
は抽象であるため、前のクラスのすべての抽象メソッドを実装する必要がないように、XmlTextWriter
から派生します。ここで間に合わせと-実装です:本番環境での使用を目的とした場合
public class EntitizingXmlWriter : XmlTextWriter
{
public EntitizingXmlWriter(TextWriter writer) :
base(writer)
{ }
public override void WriteString(string text)
{
foreach (char c in text)
{
switch (c)
{
case '\r':
case '\n':
case '\t':
base.WriteCharEntity(c);
break;
default:
base.WriteString(c.ToString());
break;
}
}
}
}
、それは非常に非効率的なので、あなたは、c.ToString()
一部を廃止したいと思います。オリジナルのtext
のサブストリングをバッチ処理して、エンタイアしたい文字を含まないコードを最適化し、それらを1つのbase.WriteString
コールにまとめてフィードすることができます。
警告の単語ベースWriteString
方法は、それによって\r
を&#xA;
に拡張させる、&
で任意&
文字を置き換えることになるので、次のナイーブな実装では、動作しません。このことができます
using (var textWriter = new StreamWriter(destination))
using (var xmlWriter = new EntitizingXmlWriter(textWriter))
document.Save(xmlWriter);
希望:
public override void WriteString(string text)
{
text = text.Replace("\r", "
");
text = text.Replace("\n", "
");
text = text.Replace("\t", "	");
base.WriteString(text);
}
最後に、ちょうど次のスニペットを使用し、先のファイルまたはストリームにあなたのXDocument
を保存します!
編集:参考のために、ここで上書きWriteString
方法の最適化バージョンは、次のとおりです。
public override void WriteString(string text)
{
// The start index of the next substring containing only non-entitized characters.
int start = 0;
// The index of the current character being checked.
for (int curr = 0; curr < text.Length; ++curr)
{
// Check whether the current character should be entitized.
char chr = text[curr];
if (chr == '\r' || chr == '\n' || chr == '\t')
{
// Write the previous substring of non-entitized characters.
if (start < curr)
base.WriteString(text.Substring(start, curr - start));
// Write current character, entitized.
base.WriteCharEntity(chr);
// Next substring of non-entitized characters tentatively starts
// immediately beyond current character.
start = curr + 1;
}
}
// Write the trailing substring of non-entitized characters.
if (start < text.Length)
base.WriteString(text.Substring(start, text.Length - start));
}
古い文書を読み込むときまたは新しい文書を保存するときに が置き換えられますか? –
@Arnold:新しいものを保存するとき。 – mahdaeng
理想的なソリューションは、XMLのコンシューマを修正して、XMLを適切に処理することです。 – svick