在以下XSD中,所有元素都是必需的:
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://TestNamespace" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://TestNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Test">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="Id" type="xs:int" />
<xs:element minOccurs="1" maxOccurs="1" name="EMail" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
但是,当我序列化xsd.exe生成的类的实例EMail == null
时,生成的XML根据模式无效,因为EMail元素完全丢失。
<?xml version="1.0"?>
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://TestNamespace">
<Id xmlns="">2</Id>
</Test>
为什么?有什么办法可以阻止吗?
答案 0 :(得分:0)
在您的评论中,您提到您希望将空值用作缺少Email
元素的默认值。
这是架构级问题,与序列化程序或代理生成器无关。
此类行为应在架构中定义,而不是留给序列化程序。不幸的是,XML Schema doesn't allow default element values因为它太复杂而无法猜测默认元素的结构是什么。它本身是否需要元素?阵列?选择元素呢?
XML Schema允许默认或固定属性值 allowed,但使用default
和fixed
属性。
一种解决方案是创建一个您认为有效的空Email
对象的实例,并使用它而不是空值。
static readonly EmptyEmail=new Email();
...
test.Email=test.Email??EmptyEmail;
实际上,这是Null Object pattern的一种情况 - 使用Null Object实例而不是null值。许多.NET Framework类将Null对象存储为类本身上名为Empty
的静态只读字段。这样可以使代码更清晰:
test.Email=test.Email??Email.Empty;
另一种选择是初始化类的构造函数中的Email
属性。 XSD生成的类是partial的,它允许您在部分文件中定义一个构造函数,在重新生成代理时不会被覆盖,例如:
public partial class Test
{
public Test()
{
Email=new Email();
}
}