문제

XML 네임 스페이스가 자동으로 직렬화되지 않고 .NET에서 객체를 직렬화 할 수있는 방법이 있습니까? 기본적으로 .NET은 XSI 및 XSD 네임 스페이스가 포함되어야한다고 생각하지만 그곳에서 원하지 않는 것 같습니다.

도움이 되었습니까?

해결책

아 ... 신경 쓰지 마라. 질문이 제기 된 후에는 항상 검색입니다. 직렬화되고있는 내 대상은입니다 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

다음과 같은 C#에서 :

//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);

다른 팁

추가를 제거하고 싶다면 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 파일을 생성하므로 출력 파일을 분해하고 더 작은 "청크"로 직렬화 할 때 일반적인 방법으로 마무리했습니다.

    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
        }
    }

이 헬퍼 클래스를 제안합니다.

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
}

:)

생성 된 클래스에서 XML로 직렬화 할 때 각 요소에 대한 추가 XMLNS 속성을 제거 할 수없는 경우 (예 : 언제 : xsd.exe 사용되었습니다), 당신은 다음과 같은 것이 있습니다.

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

그런 다음 나에게 효과가있는 것을 공유 할 것입니다 (이전 답변과 내가 찾은 것의 혼합 여기)

다른 XMLN을 다음과 같이 명시 적으로 설정하십시오.

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 /> ...
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top