为啥在 XSD 中定义为属性时,自动生成的类中的字段会序列化为元素?
Posted
技术标签:
【中文标题】为啥在 XSD 中定义为属性时,自动生成的类中的字段会序列化为元素?【英文标题】:Why is a field in an auto-generated class serialized into an element when defined as an attribute in the XSD?为什么在 XSD 中定义为属性时,自动生成的类中的字段会序列化为元素? 【发布时间】:2012-07-12 01:39:44 【问题描述】:我正在尝试通过 REST API(使用 WCF)将一个相当复杂的对象公开为 XML。
但是,该对象是由 XSD 文件定义的,因此我使用 xsd.exe 工具生成了类。问题是,似乎当我的对象被序列化为 XML 时,一个属性(在 xsd 中定义)被序列化为一个元素。我不明白为什么。目前,我假设我的 xsd 以某种方式允许这样做,但我不知道为什么。 我不做任何自定义序列化,我让框架来处理。
谁能解释为什么会发生这种情况以及如何控制这种行为?
这里是 xsd 中包含元素和属性的部分。 编辑:有问题的属性是版本
<xs:schema xmlns:b="http://some.namespace.com/" xmlns="http://someothernamespace.com/" elementFormDefault="qualified" targetNamespace="http://someothernamespace.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="JobPositionPosting.xsd" />
<xs:element name="Envelope">
<xs:complexType>
<xs:sequence>
<xs:element ref="Sender" />
<xs:element minOccurs="0" ref="TransactInfo" />
<xs:element maxOccurs="unbounded" ref="Packet" />
</xs:sequence>
<xs:attribute fixed="0.52" name="version" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
这是生成的代码。
/// <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 = "<removed>")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://somenamespace.com", IsNullable = false)]
public partial class Envelope
/// <remarks/>
public Sender Sender;
/// <remarks/>
public TransactInfo TransactInfo;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Packet")]
public Packet[] Packet;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute("version")]
public string version;
public Envelope()
this.version = "0.52";
这是从 REST 服务返回的 xml,即序列化对象。
<!-- (the rest o the xml is left out on purpose) -->
<Envelope>
<senderField i:nil="true"/>
<transactInfoField i:nil="true"/>
<versionField>0.52</versionField>
</Envelope>
谢谢!
【问题讨论】:
【参考方案1】:xsd.exe
生成供System.Xml.Serialization.XmlSerializer
使用的类,而您的 REST 服务正在使用System.Runtime.Serialization.DataContractSerializer
的某些变体。
对于DataContractSerializer
,您应该改用svcutil.exe
。
svcutil.exe /help
svcutil.exe schema.xsd /dconly
【讨论】:
我尝试了您的解决方案,但似乎 svcutil 无法处理我的 xsd。无论我尝试了什么选项,它都告诉我它无法从程序集中加载数据(这表明它不知道如何处理 xsd)。相反,我尝试修改生成的类以改为使用 XmlSerializer。我遇到了一些问题,但我希望能尽快解决。 @Anton 看来svcutil.exe
不支持XML 属性,尤其是use="required"
设置。只有xsd.exe
允许这样做。要将 XmlSerializer
与 WCF 一起使用,您可以在类上指定 XmlSerializerFormat
属性。以上是关于为啥在 XSD 中定义为属性时,自动生成的类中的字段会序列化为元素?的主要内容,如果未能解决你的问题,请参考以下文章
JAXB xs:maxLength 和 minOccurs="0" 未在 xsd 生成的类中显示