Jak serializować obiekt do XML bez uzyskiwania xmlns="..."?

Czy istnieje sposób na serializację obiektu w. Net bez automatycznej serializacji przestrzeni nazw XML? Wydaje się, że domyślnie. NET uważa, że przestrzenie nazw XSI i XSD powinny być włączone, ale nie chcę ich tam.

Author: Cheeso, 2008-11-03

5 answers

Ahh... nieważne. Zawsze poszukiwanie po zadaniu pytania daje odpowiedź. Mój obiekt, który jest serializowany to obj i został już zdefiniowany. Dodanie przestrzeni XMLSerializerNamespace z pojedynczą pustą przestrzenią nazw do kolekcji rozwiązuje problem.

W VB tak:

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

W C# tak:

//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);
 119
Author: Wes P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-01 16:42:55

Jeśli chcesz pozbyć się dodatkowych xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" i xmlns:xsd="http://www.w3.org/2001/XMLSchema", ale nadal zachować własną przestrzeń nazw xmlns="http://schemas.YourCompany.com/YourSchema/", używasz tego samego kodu jak powyżej, z wyjątkiem tej prostej zmiany:

//  Add lib namespace with empty prefix  
ns.Add("", "http://schemas.YourCompany.com/YourSchema/");   
 18
Author: Ali B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-28 00:12:59

Proponuję tę klasę pomocniczą:

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
}

:)

 6
Author: Maziar Taheri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-19 12:43:21

Jeśli chcesz usunąć przestrzeń nazw, możesz również chcieć usunąć wersję, aby zaoszczędzić Ci wyszukiwania dodałem tę funkcjonalność, więc poniższy kod zrobi oba.

Owinąłem go również metodą generyczną, ponieważ tworzę bardzo duże pliki xml, które są zbyt duże, aby serializować je w pamięci, więc rozbiłem mój plik wyjściowy i serializowałem go w mniejszych "kawałkach":

    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
        }
    }
 6
Author: D34th,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 23:54:22

Jeśli nie możesz pozbyć się dodatkowych atrybutów xmlns dla każdego elementu, podczas serializacji do xml z generowanych klas (np.: when xsd.exe został użyty), więc masz coś w stylu:

<manyElementWith xmlns="urn:names:specification:schema:xsd:one" />

Wtedy podzieliłbym się z Wami tym, co dla mnie zadziałało (mieszanka poprzednich odpowiedzi i tego, co znalazłem tutaj)

jawnie ustaw wszystkie swoje różne xmlns w następujący sposób:

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")

następnie przekaż go do serialize

serializer.Serialize(writer, object, xmlns);

będziesz miał trzy przestrzenie nazw zadeklarowane w elemencie głównym i nie muszą być generowane w innych elementach, które będą odpowiednio poprzedzone

<root xmlns:one="urn:names:specification:schema:xsd:one" ... />
   <one:Element />
   <two:ElementFromAnotherNameSpace /> ...
 4
Author: vinjenzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-12 09:19:19