xmlns =“…”を取得せずにオブジェクトをXMLにシリアル化する方法
-
06-07-2019 - |
質問
XML名前空間を自動的にシリアル化せずに、.NETでオブジェクトをシリアル化する方法はありますか?デフォルトでは、.NETはXSIとXSDのネームスペースを含めるべきだと考えていますが、それらは必要ありません。
解決
ああ...気にしないで。答えが得られるのは、常に質問が提示された後の検索です。シリアル化されているオブジェクトは obj
であり、すでに定義されています。単一の空の名前空間を持つXMLSerializerNamespaceをコレクションに追加すると、うまくいきます。
VBの場合:
Dim xs As New XmlSerializer(GetType(cEmploymentDetail))
Dim ns As New XmlSerializerNamespaces()
ns.Add("", "")
Dim settings As New XmlWriterSettings()
settings.OmitXmlDeclaration = True
Using ms As New MemoryStream(), _
sw As XmlWriter = XmlWriter.Create(ms, settings), _
sr As New StreamReader(ms)
xs.Serialize(sw, obj, ns)
ms.Position = 0
Console.WriteLine(sr.ReadToEnd())
End Using
C#の場合:
//Create our own namespaces for the output
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
//Add an empty namespace and empty value
ns.Add("", "");
//Create the serializer
XmlSerializer slz = new XmlSerializer(someType);
//Serialize the object with our own namespaces (notice the overload)
slz.Serialize(myXmlTextWriter, someObject, ns);
他のヒント
余分な xmlns:xsi =" http://www.w3.org/2001/XMLSchema-instance"
および xmlns:xsd =&quotを削除する場合; http://www.w3.org/2001/XMLSchema"
、ただし独自のネームスペース xmlns =" http://schemas.YourCompany.com/YourSchema/"
、この単純な変更を除いて、上記と同じコードを使用します。
// Add lib namespace with empty prefix
ns.Add("", "http://schemas.YourCompany.com/YourSchema/");
名前空間を削除する場合は、バージョンを削除することもできます。検索を保存するには、以下のコードで両方を実行できるようにその機能を追加しました。
また、メモリ内でシリアル化するには大きすぎる非常に大きなxmlファイルを作成するため、汎用メソッドでラップしました。そのため、出力ファイルを分割し、小さな「チャンク」でシリアル化しました:
public static string XmlSerialize<T>(T entity) where T : class
{
// removes version
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
XmlSerializer xsSubmit = new XmlSerializer(typeof(T));
using (StringWriter sw = new StringWriter())
using (XmlWriter writer = XmlWriter.Create(sw, settings))
{
// removes namespace
var xmlns = new XmlSerializerNamespaces();
xmlns.Add(string.Empty, string.Empty);
xsSubmit.Serialize(writer, entity, xmlns);
return sw.ToString(); // Your XML
}
}
このヘルパークラスを提案します:
public static class Xml
{
#region Fields
private static readonly XmlWriterSettings WriterSettings = new XmlWriterSettings {OmitXmlDeclaration = true, Indent = true};
private static readonly XmlSerializerNamespaces Namespaces = new XmlSerializerNamespaces(new[] {new XmlQualifiedName("", "")});
#endregion
#region Methods
public static string Serialize(object obj)
{
if (obj == null)
{
return null;
}
return DoSerialize(obj);
}
private static string DoSerialize(object obj)
{
using (var ms = new MemoryStream())
using (var writer = XmlWriter.Create(ms, WriterSettings))
{
var serializer = new XmlSerializer(obj.GetType());
serializer.Serialize(writer, obj, Namespaces);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
public static T Deserialize<T>(string data)
where T : class
{
if (string.IsNullOrEmpty(data))
{
return null;
}
return DoDeserialize<T>(data);
}
private static T DoDeserialize<T>(string data) where T : class
{
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(data)))
{
var serializer = new XmlSerializer(typeof (T));
return (T) serializer.Deserialize(ms);
}
}
#endregion
}
:)
生成されたクラスからxmlにシリアル化するときに(たとえば、 xsd.exe が使用されたとき)、各要素の余分なxmlns属性を取り除くことができない場合、次のようになります:
<manyElementWith xmlns="urn:names:specification:schema:xsd:one" />
それから私はあなたに私のために働いたものを共有します(以前の答えと私が見つけたものの混合こちら)
すべての異なるxmlnsを次のように明示的に設定します。
Dim xmlns = New XmlSerializerNamespaces()
xmlns.Add("one", "urn:names:specification:schema:xsd:one")
xmlns.Add("two", "urn:names:specification:schema:xsd:two")
xmlns.Add("three", "urn:names:specification:schema:xsd:three")
次にシリアル化に渡します
serializer.Serialize(writer, object, xmlns);
ルート要素で宣言された3つの名前空間があり、それに応じて接頭辞が付けられる他の要素で生成する必要はもうありません
<root xmlns:one="urn:names:specification:schema:xsd:one" ... />
<one:Element />
<two:ElementFromAnotherNameSpace /> ...