2009-07-08 2 views
1

Мое замешательство заключается в использовании .Net C# XMLSerializer для сериализации настраиваемого определенного типа с использованием файла схемы/cs, сгенерированного с помощью XSD-инструмента, из исходного исходного XML-файла. Но сгенерированное сериализованное пространство имен файлов XML отличается от исходного входного файла XML. Особенно из исходного XML-файла Envelope принадлежит пространству имен soapenv, но в сериализованном XML-файле Envelope принадлежит пространству имен по умолчанию. Какие-нибудь идеи, что не так?.Net Проблема сериализации XML

Вот как я использую XSD инструмент для создания файла схемы и CS-файл для индивидуального определенного типа из входного файла XML XMLFile1.xml,

КСТАТИ: файлы XML можно загрузить с,

http://www.mediafire.com/?nwngwzz3gmm

D:\>xsd XMLFile1.xml 
Microsoft (R) Xml Schemas/DataTypes support utility 
[Microsoft (R) .NET Framework, Version 2.0.50727.3038] 
Copyright (C) Microsoft Corporation. All rights reserved. 
Writing file 'D:\XMLFile1.xsd'. 

D:\>xsd XMLFile1.xsd XMLFile1_app1.xsd /classes 
Microsoft (R) Xml Schemas/DataTypes support utility 
[Microsoft (R) .NET Framework, Version 2.0.50727.3038] 
Copyright (C) Microsoft Corporation. All rights reserved. 
Writing file 'D:\XMLFile1_XMLFile1_app1.cs'. 

Вот как я использую C# код для сериализации файла и вывод в TestOutputFile.xml,

static void Main(string[] args) 
{ 
    Envelope en = new Envelope(); 
    en.Items = new EnvelopeBody[1]; 
    en.Items[0] = new EnvelopeBody(); 
    en.Items[0].QueryResponse = new QueryResponseFaculties[1]; 
    en.Items[0].QueryResponse[0] = new QueryResponseFaculties(); 
    en.Items[0].QueryResponse[0].Name = "John"; 

    XmlSerializer serializer = 
    new XmlSerializer(typeof(Envelope)); 
    TextWriter writer = new StreamWriter("TestOutputFile.xml"); 

    serializer.Serialize(writer, en); 
    writer.Close(); 

    return; 
} 

Оригинальный XML файл,

<?xml version="1.0" encoding="utf-8"?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
    <QueryResponse xmlns="http://schemas.mycorp.com/test"> 
     <Faculties> 
     <Name> 
      John 
     </Name> 
     </Faculties> 
    </QueryResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

Сериализованный файл XML является,

<?xml version="1.0" encoding="utf-8"?> 
<Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns="http://schemas.xmlsoap.org/soap/envelope/"> 
    <Body> 
    <QueryResponse xmlns="http://schemas.mycorp.com/test"> 
     <Faculties> 
     <Name>John</Name> 
     </Faculties> 
    </QueryResponse> 
    </Body> 
</Envelope> 

EDIT 1:

Текущий код,

static void Main(string[] args) 
{ 
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
    ns.Add("soapenv", "http://schemas.xmlsoap.org/soap/envelope/"); 
    ns.Add("", "http://schemas.mycorp.com/test"); 
    ns.Add("xsd", "http://www.w3.org/2001/XMLSchema"); 
    ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 

    Envelope en = new Envelope(); 
    en.Items = new EnvelopeBody[1]; 
    en.Items[0] = new EnvelopeBody(); 
    en.Items[0].QueryResponse = new QueryResponseFaculties[1]; 
    en.Items[0].QueryResponse[0] = new QueryResponseFaculties(); 
    en.Items[0].QueryResponse[0].Name = "John"; 

    XmlSerializer serializer = 
    new XmlSerializer(typeof(Envelope)); 
    TextWriter writer = new StreamWriter("TestOutputFile.xml"); 

    serializer.Serialize(writer, en, ns); 
    writer.Close(); 

    return; 
} 

токовый выход (сериализованный XML-файл),

<?xml version="1.0" encoding="utf-8"?> 
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://schemas.mycorp.com/test" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
    <QueryResponse> 
     <Faculties> 
     <Name>John</Name> 
     </Faculties> 
    </QueryResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

Я хочу выход быть (обратите внимание на расположение строк Xmlns = "http://schemas.mycorp.com/test"),

<?xml version="1.0" encoding="utf-8"?> 
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
    <QueryResponse xmlns="http://schemas.mycorp.com/test"> 
     <Faculties> 
     <Name>John</Name> 
     </Faculties> 
    </QueryResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

заранее спасибо, Джордж

+0

обновил свой пример, чтобы показать его работу с полным кодом –

+0

Вы твердите пространство имен находятся в неправильном месте, но когда я запускаю код, который я разместил, ваш аутпульт ** точно **, как вы просили. Интересно, является ли это версией фреймворка? Я в 3.5SP1 –

+0

Джордж, часть вашей проблемы заключается в том, что вы сериализуете конверт, а также содержимое. Зачем ты это делаешь? Вы не называете веб-сервис? –

ответ

3

Не являются ли они взаимозаменяемыми? В одном используется xmlns, чтобы установить пространство имен в элементе, а в другом - алиас xmlns:soapenv, но смысл тот же, а ИМО - вторая версия.

Класс XmlSerializerNamespaces, который может исправить это; Полный пример:

using System; 
using System.Xml.Serialization; 
[XmlRoot(Namespace="http://schemas.xmlsoap.org/soap/envelope/")] 
public class Envelope { 
    public Body Body { get; set; } 
} 
public class Body { 
    [XmlElement(Namespace="http://schemas.mycorp.com/test")] 
    public QueryResponse QueryResponse { get; set; } 
} 
public class QueryResponse { 
    public Faculties Faculties { get; set; } 
} 
public class Faculties { 
    public string Name { get; set; } 
} 
static class Program { 
    static void Main() { 
     XmlSerializer ser = new XmlSerializer(typeof(Envelope)); 
     XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
     ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
     ns.Add("xsd", "http://www.w3.org/2001/XMLSchema"); 
     ns.Add("soapenv", "http://schemas.xmlsoap.org/soap/envelope/"); 
     Envelope env = new Envelope { 
      Body = new Body { 
       QueryResponse = new QueryResponse { 
        Faculties = new Faculties { Name = "John"} 
       } 
      } 
     }; 
     ser.Serialize(Console.Out, env, ns); 
    } 
} 

Выход (@encoding из-за Console.Out):

<?xml version="1.0" encoding="ibm850"?> 
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
    <QueryResponse xmlns="http://schemas.mycorp.com/test"> 
     <Faculties> 
     <Name>John</Name> 
     </Faculties> 
    </QueryResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 
+0

Привет, Марк, я согласен с синтаксисом XML, они одинаковы. Но для ограничения моей старой программы я должен поместить Envelope в пространство имен soapenv. Любые идеи, как решить эту проблему? – George2

+0

Спасибо Marc, я пробовал ваше решение, осталось только одна незначительная проблема, и я хочу определить пространство имен по умолчанию xmlns = "schemas.mycorp.com/test из элемента QueryResponse, а не из элемента верхнего уровня Envelope, любых решений? – George2

+0

Ваше решение определит все пространства имен на элементе XML верхнего уровня XML-файла с сериализованным выходом. – George2

3

Вы должны использовать класс XmlSerializerNamespaces, чтобы настроить пространство имен, то при сериализации вам нужно передать этот экземпляр XmlSerializerNamespces вместе с вашим объектом. Вы также должны установить пространство имен ваших классов и/или свойства, используя XmlRoot и XmlElement атрибуты:

static void Main(string[] args) 
{ 
    Envelope en = new Envelope(); 
    en.Items = new EnvelopeBody[1]; 
    en.Items[0] = new EnvelopeBody(); 
    en.Items[0].QueryResponse = new QueryResponseFaculties[1]; 
    en.Items[0].QueryResponse[0] = new QueryResponseFaculties(); 
    en.Items[0].QueryResponse[0].Name = "John"; 

    XmlSerializer serializer = 
    new XmlSerializer(typeof(Envelope)); 
    TextWriter writer = new StreamWriter("TestOutputFile.xml"); 

    XmlSerlializerNamespaces xsn = new XmlSerializerNamespaces(); 
    xsn.Add("soapenv", "http://schemas.xmlsoap.org/soap/envelope/"); 

    serializer.Serialize(writer, en, xsn); 
    writer.Close(); 

    return; 
} 

[XmlRoot(Namespace="http://schemas.xmlsoap.org/soap/envelope/")] 
class Envelope 
{ 
    // ... 
} 
+0

Спасибо jrista, я пробовал ваше решение, осталось только одна незначительная проблема, которая заключается в том, что я хочу определить пространство имен по умолчанию xmlns = "http://schemas.mycorp.com/test из элемента QueryResponse, а не из элемента верхнего уровня Envelope , любые решения? – George2

+0

Ваше решение определит все пространства имен на элементе XML верхнего уровня XML-файла с сериализованным выходом. – George2

+1

Просто используйте атрибут XmlElement, чтобы задать пространство имен для любого свойства по отдельности. – jrista

Смежные вопросы