2

我创建了一个类型,它实现了 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
    }
}
4

0 回答 0