Как добавить 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, чтобы фактически получить сгенерированные классы в ваше пространство имен.