2010-06-22 16 views
14

Ich habe eine paar Erweiterungs-Methoden, die Serialisierung meiner Klassen handhaben, und da es ein zeitaufwändiger Prozess sein kann, werden sie einmal pro Klasse erstellt und auf diese Weise ausgegeben. DieseSerialisierung OHNE xmlns

public static XmlSerializer GetSerializerFor(Type typeOfT) 
{ 
    if (!serializers.ContainsKey(typeOfT)) 
    { 
     var xmlAttributes = new XmlAttributes(); 
     var xmlAttributeOverrides = new XmlAttributeOverrides(); 

     System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT)); 

     xmlAttributes.Xmlns = false; 
     xmlAttributeOverrides.Add(typeOfT, xmlAttributes); 

     var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides); 
     serializers.Add(typeOfT, newSerializer); 
    } 

    return serializers[typeOfT]; 
} 

wird durch die Extension-Methode genannt .Serialize()

public static XElement Serialize(this object source) 
{ 
    try 
    { 
     var serializer = XmlSerializerFactory.GetSerializerFor(source.GetType()); 
     var xdoc = new XDocument(); 
     using (var writer = xdoc.CreateWriter()) 
     { 
      serializer.Serialize(writer, source, new XmlSerializerNamespaces(new[] { new XmlQualifiedName("", "") })); 
     } 

     return (xdoc.Document != null) ? xdoc.Document.Root : new XElement("Error", "Document Missing"); 
    } 
    catch (Exception x) 
    { 
     return new XElement("Error", x.ToString()); 
    } 
} 

Leider, wenn Klassen Serialisierung, die automatisch generiert werden, haben sie das Attribut XmlTypeAttribute(Namespace="http://tempuri.org/") auf sie angewendet.

Dies führt dazu, dass die Deserialisierung durch die nicht automatisch generierten Gegenstücke fehlschlägt.

ich den Serializer muß den Namespace vollständig ignorieren und nicht bewerben, aber was ich im ersten Block des Codes geschrieben scheint nicht, es zu entfernen, ich am Ende noch mit xml wie diese

<Note> 
    <ID xmlns="http://tempuri.org/">12</ID> 
    <Author xmlns="http://tempuri.org/"> 
    <ID>1234</ID> 
    <Type>Associate</Type> 
    <IsAvailable>false</IsAvailable> 
    </Author> 
    <Created xmlns="http://tempuri.org/">2010-06-22T09:38:01.5024351-05:00</Created> 
    <Text xmlns="http://tempuri.org/">This is an update</Text> 
</Note> 

Anstelle des gleichen, abzüglich des xmlns="http://tempuri.org/" Attributs.

Bitte helfen, danke, das macht mich verrückt!

EDIT:

Ich kenne das Problem, nur nicht, wie es zu beheben.

Meine Klasse, ist nicht nur voll von einfachen Typen.

Es enthält Eigenschaften mit Typen anderer Klassen. Diese werden auch automatisch mit dem Attribut XmlTypeAttribute(Namespace = "http://tempuri.org/") generiert. Wenn also die Serialisierung stattfindet und die Eigenschaften meiner Klasse serialisiert werden, durchlaufen sie nicht meine benutzerdefinierte Serialisierung und haben daher das Attribut angewendet und nicht überschrieben.

Jetzt muss ich nur herausfinden, wie man diesen Reifen springt. Irgendwelche Gedanken wie?

EDIT 2:

Die folgenden Arbeiten OHNE Xmlns serialisiert ... aber ich habe ein Problem auf dem Deserialisierung Ende, nur noch nicht sicher, ob es in engen Zusammenhang steht oder nicht

public static XmlSerializer GetSerializerFor(Type typeOfT) 
{ 
    if (!serializers.ContainsKey(typeOfT)) 
    { 
     var xmlAttributes = new XmlAttributes(); 
     var xmlAttributeOverrides = new XmlAttributeOverrides(); 

     System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT)); 

     xmlAttributes.XmlType = new XmlTypeAttribute 
     { 
      Namespace = "" 
     }; 

     xmlAttributes.Xmlns = false; 

     var types = new List<Type> {typeOfT, typeOfT.BaseType}; 

     foreach (var property in typeOfT.GetProperties()) 
     { 
      types.Add(property.PropertyType); 
     } 

     types.RemoveAll(t => t.ToString().StartsWith("System.")); 

     foreach (var type in types) 
     { 
      xmlAttributeOverrides.Add(type, xmlAttributes); 
     } 

     var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides); 
     //var newSerializer = new XmlSerializer(typeOfT, xmlAttributeOverrides, extraTypes.ToArray(), new XmlRootAttribute(), string.Empty); 
     //var newSerializer = new XmlSerializer(typeOfT, string.Empty); 

     serializers.Add(typeOfT, newSerializer); 
    } 

    return serializers[typeOfT]; 
} 

EDIT3 : unter Verwendung einer Lösung von How to remove all namespaces from XML with C#?

public static XElement RemoveAllNamespaces(this XElement source) 
{ 
    return !source.HasElements 
       ? new XElement(source.Name.LocalName) 
        { 
         Value = source.Value 
        } 
       : new XElement(source.Name.LocalName, source.Elements().Select(el => RemoveAllNamespaces(el))); 
} 
+1

Ihre letzte Lösung sollte 'RemoveAllAttributes' – redtetrahedron

Antwort

3

Kein Problem Ended up - nur eine leere Zeichenfolge als den Pass Standard-Namespace auf die XML-Serializer:

XmlSerializer newSerializer = 
    new XmlSerializer(typeOfT, ""); 

Leider gibt es keine einfache Konstruktor Überlastung, wenn Sie wirklich die XmlAttributeOverrides und die Standard-Namespace definieren müssen - so können Sie entweder die XmlAttributeOverrides überspringen und dass Konstruktor ich erwähnt, oder Sie Sie müssen den Parameter verwenden, der alle möglichen Parameter definiert (einschließlich XmlAttributeOverrides und Standard-XML-Namespaces - und ein paar mehr).

+0

benannt haben, das ist, was ich vorher eigentlich hatte, es nicht funktionierte, war es immer noch den Wert aus dem XmlTypeAttribute auf die Klasse. Und ich habe gerade folgendes versucht und es hat nicht funktioniert 'var newSerializer = neuer XmlSerializer (typeOfT, xmlAttributeOverrides, neuer Type [] {}, new XmlRootAttribute()," ");' – CaffGeek

+0

string.Empty >>> "" :) – annakata

+0

@annakata, ich habe auch versucht, es mit string.Empty zu ersetzen. – CaffGeek

44

Eine funktionierende Lösung, für die Aufzeichnung!

var ns = new XmlSerializerNamespaces(); 
ns.Add("", ""); 
var serializer = new XmlSerializer(yourType); 
serializer.Serialize(xmlTextWriter, someObject, ns); 
+0

Sicherlich eine bessere Lösung. Klappt wunderbar! – user460762

+10

Für den Datensatz wird dies die 'xsi' und' xsd' entfernen, aber es wird ein neues 'xmlns: prefix = ' hinzufügen und das Präfix all Ihren Tags hinzufügen, wenn Sie 'XmlTypeAttribute's mit Namespaces in Ihrer angegeben haben Klassen. – redtetrahedron

+0

Das funktionierte wirklich perfekt für mich, nachdem ich so viele verschiedene Dinge ausprobiert hatte, die einfach nicht ohne Nebenwirkungen funktionierten. Ich danke dir sehr. – JoeFox

1
public static byte[] SerializeByteByType(object objectToSerialize, Type type) 
    { 
     XmlWriterSettings xmlSetting = new XmlWriterSettings() 
     { 
      NewLineOnAttributes = false, 
      OmitXmlDeclaration = true, 
      Indent = false, 
      NewLineHandling = NewLineHandling.None, 
      Encoding = Encoding.UTF8, 
      NamespaceHandling = NamespaceHandling.OmitDuplicates 
     }; 

     using (MemoryStream stm = new MemoryStream()) 
     { 
      using (XmlWriter writer = XmlWriter.Create(stm, xmlSetting)) 
      { 
       var xmlAttributes = new XmlAttributes(); 
       var xmlAttributeOverrides = new XmlAttributeOverrides(); 

       xmlAttributes.Xmlns = false; 
       xmlAttributes.XmlType = new XmlTypeAttribute() { Namespace = "" }; 
       xmlAttributeOverrides.Add(type, xmlAttributes); 

       XmlSerializer serializer = new XmlSerializer(type, xmlAttributeOverrides); 
       //Use the following to serialize without namespaces 
       XmlSerializerNamespaces xmlSrzNamespace = new XmlSerializerNamespaces(); 
       xmlSrzNamespace.Add("", ""); 

       serializer.Serialize(writer, objectToSerialize, xmlSrzNamespace); 
       stm.Flush(); 
       stm.Position = 0; 
      } 

      return stm.ToArray(); 
     } 
    }   
+0

Stattdessen "xmlAttributeOverrides.Add (type, xmlAttributes);" sein muss: „var types = type.Assembly.GetTypes() Wo (t => String.Equals (t.Namespace, currentType.Namespace, StringComparison.Ordinal)); var XmlAttributeOverrides = new XmlAttributeOverrides(); \t \t \t. foreach (var t in Typen) \t xmlAttributeOverrides.Add (t, xmlAttributes); " – Mentor