Есть ли способ для меня сериализовать объект в .NET без пространственных имен XML-пространств? Похоже, что по умолчанию .NET полагает, что пространства имен XSI и XSD должны быть включены, но я не хочу их там.
Как сериализовать объект в XML без получения xmlns = "..."?
Ответ 1
Ах... никогда. Это всегда поиск после постановки вопроса, который дает ответ. Мой объект, который сериализуется, 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
в С#, например:
//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);
Ответ 2
Если вы хотите избавиться от дополнительных xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" и xmlns:xsd="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 Serialization здесь.
Ответ 3
Если вы хотите удалить пространство имен, вы также можете удалить эту версию, чтобы сохранить поиск. Я добавил эту функциональность, чтобы нижний код выполнял оба.
Я также обернул его в общий метод, так как я создаю очень большие 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
        }
    }
Ответ 4
Я предлагаю этот вспомогательный класс:
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
}
:)
Ответ 5
Если вы не можете избавиться от дополнительных атрибутов xmlns для каждого элемента, при сериализации в xml из сгенерированных классов (например: когда xsd.exe), так что у вас есть что-то вроде:
<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);
у вас будут три пространства имен, объявленные в корневом элементе, и больше не нужно генерировать в других элементах, которые будут иметь префикс соответственно
<root xmlns:one="urn:names:specification:schema:xsd:one" ... />
   <one:Element />
   <two:ElementFromAnotherNameSpace /> ...
