简体   繁体   中英

How Can I add an XSI type to an element that is being serialized using LINQ

I want to serialize an Object of a Type of a particular class and containing a particular XSI Type

Can I Do this in LINQ ?

LINQ stands for Language-Integrated-Query and that is what it is: a query technology that allows you to query data from a variety of data sources into an object result. You want to do something completely different, so LINQ is just the wrong tool.

Also, I guess the xsd.exe that is used to generate classes from an example XML file (or schema) won't help you very much because afaik it is not clever enough to detect inheritance between schema classes.

Therefore, I would recommend to write an XML schema manually and then use xsd.exe to generate classes for that schema. You could then instantiate those classes and the XmlSerializer will give you an output as you expect.

The schema should somewhat like the following (I excluded the actual model content here, you have to choose whether to put that in Model or SettingsModel ).

<xs:element name="Model" type="Model" />
<xs:class name="Model" abstract="True">
  <xs:complexContent />
</xs:class>
<xs:class name="SettingsModel">
  <xs:complexContent>
    <xs:extension base="Model" />
  </xs:complexContent>
</xs:class>

To get the following XML:

<Model xsi:type="SettingsModel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Name>Test05</Name>
  <IsActive>false</IsActive>
  <IsHidden>false</IsHidden>
</Model>

You can use the following code:

var model = new { Name = "Test05", IsActive = false, IsHidden = false };

var namespaceName = "http://www.w3.org/2001/XMLSchema-instance";
XNamespace xsi = XNamespace.Get(namespaceName);
var x = new XElement("Model",
    new XAttribute(xsi + "type", "SettingsModel"),
    new XAttribute(XNamespace.Xmlns + "xsi", namespaceName),
    new XElement("Name", model.Name),
    new XElement("IsActive", model.IsActive),
    new XElement("IsHidden", model.IsHidden)
    );

Console.WriteLine(x);

LINQ to XML is an exercise in frustration. In the long term you may prefer to use concrete classes with appropriate XML serialization decorators.

=== edit ===

Here is some additional code that writes the data to an XML file:

var settings = new XmlWriterSettings()
{
    Indent = true,
    OmitXmlDeclaration = true
};
using (var stream = new FileStream("Test05.xml", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
using (var writer = XmlWriter.Create(stream, settings))
{
    x.WriteTo(writer);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM