Antworten:
Ahh ... egal. Es ist immer die Suche nach der Frage, die die Antwort liefert. Mein Objekt, das serialisiert wird, istobj
und wurde bereits definiert. Das Hinzufügen eines XMLSerializerNamespace mit einem einzelnen leeren Namespace zur Sammlung reicht aus.
In VB so:
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
in C # so:
//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
Mist loszuwerden ?
Wenn Sie das zusätzliche xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
und xmlns:xsd="http://www.w3.org/2001/XMLSchema"
dennoch Ihren eigenen Namespace entfernen möchten xmlns="http://schemas.YourCompany.com/YourSchema/"
, verwenden Sie bis auf diese einfache Änderung denselben Code wie oben:
// Add lib namespace with empty prefix
ns.Add("", "http://schemas.YourCompany.com/YourSchema/");
Wenn Sie den Namespace entfernen möchten, möchten Sie möglicherweise auch die Version entfernen. Um Ihnen die Suche zu ersparen, habe ich diese Funktionalität hinzugefügt, damit der folgende Code beides kann.
Ich habe es auch in eine generische Methode eingeschlossen, da ich sehr große XML-Dateien erstelle, die zu groß sind, um im Speicher zu serialisieren. Daher habe ich meine Ausgabedatei aufgeschlüsselt und in kleinere "Blöcke" serialisiert:
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
standardmäßig die UTF-16-Codierung verwendet wird, die zu nachgeschalteten Deserialisierungsproblemen führen kann. using (var reader = XmlReader.Create(stream)){ reader.Read(); }
Dies löst eine Ausnahme aus, da in der Deklaration angegeben ist, dass es sich um UTF-16 handelt, während der Inhalt tatsächlich als UTF-8 geschrieben wurde. System.Xml.XmlException: 'There is no Unicode byte order mark. Cannot switch to Unicode.'
XmlReader
, können Sie verwenden. var streamReader = new StreamReader(stream, System.Text.Encoding.UTF8, true);
The true verwendet die Stückliste, falls gefunden, andernfalls die von Ihnen angegebene Standardeinstellung.
Ich schlage diese Hilfsklasse vor:
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})
statt new XmlSerializerNamespaces(new[] {new XmlQualifiedName("", "")})
ist meiner Meinung nach eine absichtlich klarere Möglichkeit, es zu codieren.
Wenn Sie nicht in der Lage sind, zusätzliche xmlns-Attribute für jedes Element zu entfernen , wenn Sie aus generierten Klassen in xml serialisieren (z. B. wenn xsd.exe verwendet wurde), haben Sie Folgendes :
<manyElementWith xmlns="urn:names:specification:schema:xsd:one" />
dann würde ich mit Ihnen teilen, was für mich funktioniert hat (eine Mischung aus früheren Antworten und dem, was ich hier gefunden habe )
Stellen Sie alle Ihre verschiedenen XML-Dateien explizit wie folgt ein:
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")
Übergeben Sie es dann an die Serialisierung
serializer.Serialize(writer, object, xmlns);
Sie haben die drei Namespaces im Stammelement deklariert und müssen nicht mehr in den anderen Elementen generiert werden, denen ein entsprechendes Präfix vorangestellt wird
<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();
}