我创建了一个类型,它实现了 IXmlSerializable 并使用 XmlSchemaProviderAttribute 来定义其架构,以便在 WCF 服务中使用。据我所知,所有这些都根据“最佳实践”/MSDN。
长话短说,出于各种原因(不能使用 DataContract),我必须使用 IXmlSerializable,并且我希望通过使用 xs:annotation 和 xs:documentation 在 XSD 模式中记录我的类型。似乎除了类型本身之外的所有内容都可以进行注释,以某种方式从模式中剥离了类型注释。
谁能解释为什么,我的代码有什么问题或可行的解决方案?
使用下面的类作为操作的参数/返回值,或作为 DataContract 的一部分,正确地将 ComplexType 添加到模式中,除了类型注释之外的所有内容。
具体来说,这一行没有任何效果(尽管在 return 语句中有一个断点,但我可以验证注解确实存在,看起来是正确的):
type.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Documentation for MyClass") });
完整样本:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="MyNamespace" elementFormDefault="qualified" targetNamespace="MyNamespace">
<xs:complexType name="MyClass">
<xs:sequence>
<xs:element name="MyId" type="xs:integer">
<xs:annotation>
<xs:documentation>Annotation for id element</xs:documentation>
</xs:annotation>
</xs:element>
<xs:choice>
<xs:element name="MyStringChoice" type="xs:string">
<xs:annotation>
<xs:documentation>Choice number 1</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="MyIntChoice" type="xs:integer">
<xs:annotation>
<xs:documentation>Choice number 2</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:element name="MyClass" nillable="true" type="tns:MyClass"/>
</xs:schema>
[XmlSchemaProvider("GenerateSchema")]
public class MyClass : IXmlSerializable
{
public static XmlQualifiedName GenerateSchema(XmlSchemaSet schemas)
{
//Create choice
var choice = new XmlSchemaChoice();
var choice1 = new XmlSchemaElement
{
Name = "MyStringChoice",
SchemaTypeName = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String).QualifiedName,
Annotation = new XmlSchemaAnnotation()
};
var choice2 = new XmlSchemaElement
{
Name = "MyIntChoice",
SchemaTypeName = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Integer).QualifiedName,
Annotation = new XmlSchemaAnnotation()
};
choice1.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Choice number 1") });
choice2.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Choice number 2") });
choice.Items.Add(choice1);
choice.Items.Add(choice2);
//Create id element
var id = new XmlSchemaElement
{
Name = "MyId",
SchemaTypeName = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Integer).QualifiedName,
Annotation = new XmlSchemaAnnotation()
};
id.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Annotation for id element") });
//Create sequence
var sequence = new XmlSchemaSequence();
sequence.Items.Add(id);
sequence.Items.Add(choice);
//Create type
var type = new XmlSchemaComplexType
{
Name = "MyClass",
Particle = sequence,
Annotation = new XmlSchemaAnnotation()
};
//ANNOTATE TYPE: THIS DOES NOT WORK!!!!!!!
type.Annotation.Items.Add(new XmlSchemaDocumentation { Markup = TextToMarkup("Documentation for MyClass") });
//Add type to schema
var schema = GetOrCreateSchema(schemas, "MyNamespace");
schema.Items.Add(type);
//Return XmlQualifiedName for non-anonymous types
return new XmlQualifiedName("MyClass", "MyNamespace");
}
/// <summary>
/// Create a
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private static XmlNode[] TextToMarkup(string text)
{
var doc = new XmlDocument();
var t = doc.CreateTextNode(text);
return new XmlNode[] {t};
}
/// <summary>
/// Find schema matching the namespace, or create and add schema to set if it doesn't exist
/// </summary>
private static XmlSchema GetOrCreateSchema(XmlSchemaSet schemas, string targetNamespace)
{
var schema = schemas.Schemas(targetNamespace).OfType<XmlSchema>().FirstOrDefault();
if (schema == null)
{
schema = new XmlSchema
{
TargetNamespace = targetNamespace,
ElementFormDefault = XmlSchemaForm.Qualified
};
schemas.Add(schema);
}
return schema;
}
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
//Implementation ommited
}
public void WriteXml(XmlWriter writer)
{
//Implementation ommited
}
}