Как добавить xsi schemalocation в корневой объект c # XmlSerializer

Я использую XmlSerializer для создания объекта, представляющего XML-файл, и теперь я хочу добавить schemalocation к rootelement моего xml-файла. Я могу добавить пространства имен, такие как

        XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
        System.IO.FileStream fs = new FileStream(@"C:test.xml", FileMode.Create);
        TextWriter writer = new StreamWriter(fs, new UTF8Encoding());

        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("xy","http://www.w3.org/2005/08/addressing");
        ns.Add("xlink","http://www.w3.org/1999/xlink");
        serializer.Serialize(writer, myObject, ns);

но как добавить xsi:schemalocation атрибут моего корневого элемента в моем коде c#. Пространство имен было добавлено с помощью простого ns.Add(). Я бы хотел избежать возни с xsd.exe сгенерированный класс c#. Или мне нужно вручную отредактировать сгенерированный класс c# и добавить атрибут корневой элемент моего xml?

EDIT: Я видел примеры, когда мне нужно редактировать мой c# вручную, но должен быть способ сделать это в коде!! Если мы можем добавить пространства имен в наш корневой элемент, Почему нельзя добавить schemalocations?

2 ответов


предположим следующее XSD:

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="elementB">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="FirstName" type="xsd:string"/>
                <xsd:element name="LastName" type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>  
</xsd:schema>

есть два способа, по крайней мере, сделать это. Первый зависит от наследования и того, как вы можете играть с аннотациями сериализатора.

xsd.exe в создает это:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.18034
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.0.30319.1.
// 

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://tempuri.org/XMLSchema.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://tempuri.org/XMLSchema.xsd", IsNullable=false)]
public partial class elementB {

    private string firstNameField;

    private string lastNameField;

    /// <remarks/>
    public string FirstName {
        get {
            return this.firstNameField;
        }
        set {
            this.firstNameField = value;
        }
    }

    /// <remarks/>
    public string LastName {
        get {
            return this.lastNameField;
        }
        set {
            this.lastNameField = value;
        }
    }
}

"впрыснуть"xsi:schemaLocation добавить новый класс elementA : elementB; обратите внимание:


    xsd-файле.exe генерирует частичные классы, поэтому вы можете добавить свой собственный отдельный частичный класс для хранения таких вещей, как xsi:schemaLocation как поля или свойства.

    Итак, добавляя к образцу класса elementB @Petru Gardea, вам нужно только создать еще один файл в вашем проекте и добавить этот частичный класс:

    public partial class elementB 
    {
        [XmlAttributeAttribute("schemaLocation", Namespace="http://www.w3.org/2001/XMLSchema-instance")]
        public string xsiSchemaLocation = "http://www.acme.com/xml/OrderXML-1-0.xsd";
    }
    

    есть один gotcha, с которым я столкнулся, делая это, и это было по умолчанию xsd.exe не добавляет пространство имен в сгенерированные файлы. Когда вы создаете это частичное собственный класс, скорее всего, будет находиться в пространстве имен. С пространство имен по умолчанию> и явно определенное пространство имен не совпадают, частичное не будет работать. Таким образом, вам нужно использовать параметр namespace на xsd.exe, чтобы фактически получить сгенерированные классы в ваше пространство имен.