Jawaban:
Ahh ... lupakan. Itu selalu pencarian setelah pertanyaan diajukan yang menghasilkan jawabannya. Objek saya yang sedang diserialisasi adalah obj
dan telah ditentukan. Menambahkan XMLSerializerNamespace dengan satu namespace kosong ke koleksi akan berhasil.
Di VB seperti ini:
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
di C # seperti ini:
//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);
q1
omong kosong itu?
Jika Anda ingin membuang ekstra xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
dan xmlns:xsd="http://www.w3.org/2001/XMLSchema"
, tetapi tetap mempertahankan namespace Anda sendiri xmlns="http://schemas.YourCompany.com/YourSchema/"
, Anda menggunakan kode yang sama seperti di atas kecuali untuk perubahan sederhana ini:
// Add lib namespace with empty prefix
ns.Add("", "http://schemas.YourCompany.com/YourSchema/");
Jika Anda ingin menghapus namespace Anda mungkin juga ingin menghapus versinya, untuk menghemat pencarian, saya telah menambahkan fungsionalitas itu sehingga kode di bawah ini akan melakukan keduanya.
Saya juga membungkusnya dengan metode umum karena saya membuat file xml yang sangat besar yang terlalu besar untuk diserialkan dalam memori jadi saya telah memecah file keluaran saya dan membuat serial dalam "potongan" yang lebih kecil:
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
}
}
StringWriter
defaultnya ke UTF-16 Encoding yang dapat menyebabkan masalah deserialisasi di hilir. using (var reader = XmlReader.Create(stream)){ reader.Read(); }
Ini memunculkan pengecualian karena deklarasi menyatakannya sebagai UTF-16 sedangkan konten sebenarnya ditulis sebagai UTF-8. System.Xml.XmlException: 'There is no Unicode byte order mark. Cannot switch to Unicode.'
XmlReader
, Anda dapat menggunakan var streamReader = new StreamReader(stream, System.Text.Encoding.UTF8, true);
The true akan menggunakan BOM jika ditemukan, jika tidak default yang Anda sediakan.
Saya menyarankan kelas penolong ini:
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
}
:)
new XmlSerializerNamespaces(new[] {XmlQualifiedName.Empty})
alih-alih new XmlSerializerNamespaces(new[] {new XmlQualifiedName("", "")})
adalah cara yang lebih jelas untuk mengkodekannya, menurut pendapat saya.
Jika Anda tidak dapat menyingkirkan atribut xmlns tambahan untuk setiap elemen, saat membuat serial ke xml dari kelas yang dihasilkan (misalnya: ketika xsd.exe digunakan), Anda memiliki sesuatu seperti:
<manyElementWith xmlns="urn:names:specification:schema:xsd:one" />
maka saya akan berbagi dengan Anda apa yang berhasil untuk saya (campuran dari jawaban sebelumnya dan apa yang saya temukan di sini )
setel secara eksplisit semua xmlns Anda yang berbeda sebagai berikut:
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")
lalu berikan ke serialize tersebut
serializer.Serialize(writer, object, xmlns);
Anda akan memiliki tiga ruang nama yang dideklarasikan di elemen root dan tidak perlu lagi dibuat di elemen lain yang akan diawali dengan semestinya
<root xmlns:one="urn:names:specification:schema:xsd:one" ... />
<one:Element />
<two:ElementFromAnotherNameSpace /> ...
XmlWriterSettings settings = new XmlWriterSettings
{
OmitXmlDeclaration = true
};
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
StringBuilder sb = new StringBuilder();
XmlSerializer xs = new XmlSerializer(typeof(BankingDetails));
using (XmlWriter xw = XmlWriter.Create(sb, settings))
{
xs.Serialize(xw, model, ns);
xw.Flush();
return sb.ToString();
}