XsdGen:通过自定义Attribute与反射自动生成XSD

前言

系统之间的数据交互往往需要事先定义一些契约,在WCF中我们需要先编写XSD文件,然后通过自动代码生成工具自动生成C#对象。对于刚刚接触契约的人来说,掌握XMLSpy之类的软件之后确实比手写XML效率要高,但还是有些学习成本的。此外XML的tag太多,如果设计的类型属性过多,手写XSD也不太现实,很难专注于设计。

于是我想能不能先用C#写好类型,然后自动生成标准格式的XSD呢。经过三天左右的设计和实现,目前实现了以下功能:

1. 支持Class和Enum类型的设计

2. 支持基元类型、自定义类型、泛型列表、自定义类型数组等属性

3. 支持自定义类型之间的依赖关系

4. 支持契约分组(指定Request/Response分到同一个xsd文件)

5. 支持契约汇总(对于自定义类型,最终体现在一个汇总xsd文件中,并自动引用其它xsd文件)

开源地址:https://github.com/CreateChen/XsdGen。我刚接触SOA不久,目前只添加了xsd的minOccurs、maxOccurs等基本属性,对于其它属性并没有全部集成进去,集成方式也非常简单,在Attribute中添加相应的属性,并在XsdBuilder.cs中添加相应的处理。

效果

先看一下实现的效果,例如我定义了以下类型:FoodOrderRequest、FoodOrderResponse、PayType

using System;
using System.Collections.Generic;
using XsdAttribute;

[assembly: XsdSchema(
    TargetNamespace = "http://xx.com/framework/soa/sample/v1",
    XmlNamespace = "http://xx.com/framework/soa/sample/v1",
    Namespace = "http://xx.com/framework/soa/sample/v1",
    Common = "http://xx.com/common/types/v1")]
[assembly: XsdImport(Id = "SOACommonTypes",
    Namespace = "http://xx.com/common/types/v1",
    SchemaLocation = "SOACommonTypes_V1.0.0.xsd")]

namespace TestDLL
{
    [XsdComplexType(Annotation = "订餐申请", FileGroup = "FoodOrder")]
    public class FoodOrderRequest
    {
        [XsdElement(MinOccurs = "1", Annotation = "餐馆编号")]
        public int RestaurantId { get; set; }

        [XsdElement(MinOccurs = "1", Annotation = "餐馆名称")]
        public string RestaurantName { get; set; }

        [XsdElement(Annotation = "订餐日期")]
        public DateTime OrderDate { get; set; }

        [XsdElement(MinOccurs = "0", MaxOccurs = "unbounded", Annotation = "食品编号")]
        public List<int> FoodId { get; set; }

        [XsdElement(MinOccurs = "1", Annotation = "业务类型")]
        public PayType BusinessType { get; set; }
    }

    [XsdComplexType(Annotation = "订餐结果", FileGroup = "FoodOrder")]
    public class FoodOrderResponse
    {
        [XsdElement(MinOccurs = "1", Annotation = "订单编号")]
        public int OrderId { get; set; }

        [XsdElement(Annotation = "预计送达时间")]
        public DateTime DeliveryTime { get; set; }
    }

    [XsdSimpleType(Annotation = "付款类型", FileGroup = "PayType")]
    public enum PayType
    {
        现金,
        支付宝,
        微信,
        网银
    }
}

工具自动为我生成了3个文件:

FoodOrder.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="FoodOrder" targetNamespace="http://xx.com/framework/soa/sample/v1" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://xx.com/framework/soa/sample/v1" xmlns:ns="http://xx.com/framework/soa/sample/v1" xmlns:common="http://xx.com/common/types/v1">
  <xs:include schemaLocation="PayType.xsd" />
  <xs:import id="SOACommonTypes" schemaLocation="SOACommonTypes_V1.0.0.xsd" namespace="http://xx.com/common/types/v1" />
  <xs:complexType name="FoodOrderRequestType">
    <xs:annotation>
      <xs:documentation>订餐申请</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="RestaurantId" type="xs:int" minOccurs="1">
        <xs:annotation>
          <xs:documentation>餐馆编号</xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="RestaurantName" type="xs:string" minOccurs="1">
        <xs:annotation>
          <xs:documentation>餐馆名称</xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="OrderDate" type="xs:dateTime">
        <xs:annotation>
          <xs:documentation>订餐日期</xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="FoodId" type="xs:int" minOccurs="0" maxOccurs="unbounded">
        <xs:annotation>
          <xs:documentation>食品编号</xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="BusinessType" type="PayType" minOccurs="1">
        <xs:annotation>
          <xs:documentation>业务类型</xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="FoodOrderResponseType">
    <xs:annotation>
      <xs:documentation>订餐结果</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="OrderId" type="xs:int" minOccurs="1">
        <xs:annotation>
          <xs:documentation>订单编号</xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="DeliveryTime" type="xs:dateTime">
        <xs:annotation>
          <xs:documentation>预计送达时间</xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

PayType.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="PayType" targetNamespace="http://xx.com/framework/soa/sample/v1" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://xx.com/framework/soa/sample/v1" xmlns:ns="http://xx.com/framework/soa/sample/v1" xmlns:common="http://xx.com/common/types/v1">
  <xs:import id="SOACommonTypes" schemaLocation="SOACommonTypes_V1.0.0.xsd" namespace="http://xx.com/common/types/v1" />
  <xs:simpleType name="PayType" final="restriction">
    <xs:restriction base="xs:string">
      <xs:enumeration value="现金" />
      <xs:enumeration value="支付宝" />
      <xs:enumeration value="微信" />
      <xs:enumeration value="网银" />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

TestDLL.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="TestDLL" targetNamespace="http://xx.com/framework/soa/sample/v1" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://xx.com/framework/soa/sample/v1" xmlns:ns="http://xx.com/framework/soa/sample/v1" xmlns:common="http://xx.com/common/types/v1">
  <xs:import id="SOACommonTypes" schemaLocation="SOACommonTypes_V1.0.0.xsd" namespace="http://xx.com/common/types/v1" />
  <xs:include schemaLocation="FoodOrder.xsd" />
  <xs:include schemaLocation="PayType.xsd" />
  <xs:element name="FoodOrderRequest" nillable="true" type="ns:FoodOrderRequestType" />
  <xs:element name="FoodOrderResponse" nillable="true" type="ns:FoodOrderResponseType" />
</xs:schema>

自定义Attribute

1. Assembly的Attribute

[AttributeUsage(AttributeTargets.Assembly)]
public class XsdSchema : Attribute
{
    public string TargetNamespace { get; set; }
    public string XmlNamespace { get; set; }
    public string Namespace { get; set; }
    public string Common { get; set; }

    //汇总dll中的类型,生成总的xsd
    private string _packageId;
    /// <summary>
    /// 生成XSD的文件名称
    /// </summary>
    public string PackageId
    {
        get { return _packageId; }
        set
        {
            //去除文件名中非法字符
            var regex = new Regex(@"\:|\;|\/|\\|\||\,|\*|\?|\""|\<|\>");
            _packageId = regex.Replace(value, "");
        }
    }

    public static XsdSchema Get(Assembly assembly)
    {
        return (XsdSchema) GetCustomAttribute(assembly, typeof (XsdSchema));
    }
}

前几个是一些命名空间的定义,可以根据自己公司的业务规则进行设计。默认情况下,汇总文件的targetId、文件名称以及生成的文件夹名称都是PackageId决定,如果dll没有指定该值,默认则是dll的Name。

除了定义Schema,每个xsd文件中可能还需要导入一些默认的公共类型,在这种情况下,可以为assembly添加如下Attribute:

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class XsdImport : Attribute
{
    public string Id { get; set; }
    public string SchemaLocation { get; set; }
    public string Namespace { get; set; }

    public static IEnumerable<XsdImport> Get(Assembly assembly)
    {
        var attributes = GetCustomAttributes(assembly, typeof (XsdImport));
        return attributes.Cast<XsdImport>();
    }
}

2. Class类型的Attribute

[AttributeUsage((AttributeTargets.Class))]
public class XsdComplexType : Attribute
{
    private string _fileGroup;

    /// <summary>
    /// 生成XSD的文件名称
    /// </summary>
    public string FileGroup
    {
        get { return _fileGroup; }
        set
        {
            //去除文件名中非法字符
            var regex = new Regex(@"\:|\;|\/|\\|\||\,|\*|\?|\""|\<|\>");
            _fileGroup = regex.Replace(value, "");
        }
    }

    public string Annotation { get; set; }

    public static XsdComplexType Get(Type type)
    {
        return (XsdComplexType) GetCustomAttribute(type, typeof (XsdComplexType));
    }
}

其中必须指定FileGroup值,相同的FileGroup值,最后会生成到同一个xsd文件中。

2. Property的Attribute

[AttributeUsage((AttributeTargets.Property))]
public class XsdElement : Attribute
{
    public string MinOccurs { get; set; }
    public string MaxOccurs { get; set; }
    public string Annotation { get; set; }

    public static XsdElement Get(PropertyInfo propertyInfo)
    {
        return (XsdElement) GetCustomAttribute(propertyInfo, typeof (XsdElement));
    }
}

如果自定义类型的属性是List或者Array,要将MaxOccurs设为大于0的数或者unbounded。

3. Enum类型的Attribute

[AttributeUsage((AttributeTargets.Enum))]
public class XsdSimpleType : Attribute
{
    private string _fileGroup;

    /// <summary>
    /// 生成XSD的文件名称
    /// </summary>
    public string FileGroup
    {
        get { return _fileGroup; }
        set
        {
            //去除文件名中非法字符
            var regex = new Regex(@"\:|\;|\/|\\|\||\,|\*|\?|\""|\<|\>");
            _fileGroup = regex.Replace(value, "");
        }
    }

    public string Annotation { get; set; }

    public static XsdSimpleType Get(Type type)
    {
        return (XsdSimpleType) GetCustomAttribute(type, typeof (XsdSimpleType));
    }
}

与XsdComplexType类似,相同的FileGroup类型,最后都归到同一个xsd文件中。

反射DLL并生成XSD

1. XsdFile结构定义

public class XsdFile
{
    public XsdFile()
    {
        Imports = new List<XElement>();
        Elements = new List<XElement>();
    }

    public XElement Schema { get; set; }

    /// <summary>
    ///     <para>Assembly级别的Import</para>
    ///     <para>自定义复合对象的Import</para>
    /// </summary>
    public List<XElement> Imports { get; set; }

    /// <summary>
    ///     <para>自定义Class类型</para>
    ///     <para>自定义枚举类型</para>
    /// </summary>
    public List<XElement> Elements { get; set; }

    public XElement ToXML()
    {
        foreach (var import in Imports)
        {
            Schema.Add(import);
        }
        foreach (var element in Elements)
        {
            Schema.Add(element);
        }
        return Schema;
    }
}

基本思路是Schema添加所有的Import和Element,最后生成XML。

2. XsdBuilder

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using XsdAttribute;

namespace XsdGen
{
    public class XsdBuilder
    {
        private readonly XNamespace _xs = "http://www.w3.org/2001/XMLSchema";
        private Assembly _assembly;

        //Key:FileGroup, Value:对应的XsdFile
        private Dictionary<string, XsdFile> _xsdFiles;

        //自定义Class对象的声明,用于生成汇总xsd
        private List<XElement> _elements;

        public void Build(Assembly assembly)
        {
            _assembly = assembly;
            _xsdFiles = new Dictionary<string, XsdFile>();
            _elements = new List<XElement>();

            XElement[] defaultImports = GetDefaultImports(_assembly).ToArray();
            XsdSchema defaultSchema = XsdSchema.Get(_assembly);

            string directoryName = defaultSchema.PackageId ?? _assembly.GetName().Name;
            if (!Directory.Exists(directoryName))
            {
                Directory.CreateDirectory(directoryName);
            }

            BuildTypes(_assembly);
            foreach (var item in _xsdFiles)
            {
                item.Value.Schema = GetSchema(defaultSchema, item.Key);
                foreach (var import in defaultImports)
                {
                    item.Value.Imports.Add(import);
                }
                //生成XSD文件
                string fileName = string.Format("{0}/{1}.xsd", directoryName, item.Key);
                item.Value.ToXML().Save(fileName);
                Console.WriteLine("Generate {0}", fileName);
            }
            //生成汇总XSD文件
            var summaryXsdFile = BuildSummary(defaultSchema, defaultImports, directoryName);
            string summaryXsdFileName = string.Format("{0}/{1}.xsd", directoryName, directoryName);
            summaryXsdFile.ToXML().Save(summaryXsdFileName);
            Console.WriteLine("{0}Generate Summary{0}\n{1}", new String(‘=‘, 10), summaryXsdFileName);
        }

        private XElement GetSchema(XsdSchema xsdSchema, string id)
        {
            var schema = new XElement(
                _xs + "schema",
                new XAttribute("id", id),
                new XAttribute("targetNamespace", xsdSchema.TargetNamespace),
                new XAttribute("elementFormDefault", "qualified"),
                new XAttribute("attributeFormDefault", "unqualified"),
                new XAttribute(XNamespace.Xmlns + "xs", _xs.ToString())
                );
            if (!string.IsNullOrEmpty(xsdSchema.XmlNamespace))
                schema.SetAttributeValue("xmlns", xsdSchema.XmlNamespace);
            if (!string.IsNullOrEmpty(xsdSchema.Namespace))
                schema.SetAttributeValue(XNamespace.Xmlns + "ns", xsdSchema.Namespace);
            if (!string.IsNullOrEmpty(xsdSchema.Common))
                schema.SetAttributeValue(XNamespace.Xmlns + "common", xsdSchema.Common);
            return schema;
        }

        private IEnumerable<XElement> GetDefaultImports(Assembly assembly)
        {
            var xsdImports = XsdImport.Get(assembly);

            return xsdImports.Select(xsdImport => new XElement(
                _xs + "import",
                new XAttribute("id", xsdImport.Id),
                new XAttribute("schemaLocation", xsdImport.SchemaLocation),
                new XAttribute("namespace", xsdImport.Namespace)
                ));
        }

        private void BuildTypes(Assembly assembly)
        {
            var types = assembly.GetTypes();
            foreach (var type in types)
            {
                string fileGroup;
                if (type.IsClass)
                {
                    var element = BuildElement(type);
                    _elements.Add(element);
                    //_xsdFiles[fileGroup].Elements.Add(element);

                    var complexTypeElement = BuildComplexType(type, out fileGroup);
                    _xsdFiles[fileGroup].Elements.Add(complexTypeElement);
                }
                else if (type.IsEnum)
                {
                    var simpleTypeElement = BuildSimpleType(type, out fileGroup);
                    _xsdFiles[fileGroup].Elements.Add(simpleTypeElement);
                }
            }
        }

        public XElement BuildElement(Type type)
        {
            //只有Request或者Response对象类型,末尾自动添加Type
            string name = (type.Name.EndsWith("Request") || type.Name.EndsWith("Response"))
                ? type.Name + "Type"
                : type.Name;

            return new XElement(
                _xs + "element",
                new XAttribute("name", type.Name),
                    new XAttribute("nillable", true),
                new XAttribute("type", "ns:" + name)
                );
        }

        private XElement BuildComplexType(Type type, out string fileGroup)
        {
            var xsdComplexType = XsdComplexType.Get(type);
            //添加XSD文件
            fileGroup = xsdComplexType.FileGroup;
            SetDefaultFile(fileGroup);

            //只有Request或者Response对象类型,末尾自动添加Type
            string name = (type.Name.EndsWith("Request") || type.Name.EndsWith("Response"))
                ? type.Name + "Type"
                : type.Name;

            var complexTypeElement = new XElement(
                _xs + "complexType",
                new XAttribute("name", name)
                );

            if (!string.IsNullOrEmpty(xsdComplexType.Annotation))
            {
                complexTypeElement.Add(new XElement(
                    _xs + "annotation",
                    new XElement(_xs + "documentation", xsdComplexType.Annotation)
                    ));
            }

            var sequenceElement = BuildSequence(type);
            AddProperties(type, sequenceElement);
            complexTypeElement.Add(sequenceElement);
            return complexTypeElement;
        }

        private XElement BuildSequence(Type type)
        {
            var sequence = new XElement(_xs + "sequence");return sequence;
        }

        private XsdFile BuildSummary(XsdSchema defaultSchema, XElement[] defaultImports, string packageId)
        {
            XsdFile xsdFile = new XsdFile();
            xsdFile.Schema = GetSchema(defaultSchema, packageId);
            foreach (var import in defaultImports)
            {
                xsdFile.Imports.Add(import);
            }
            //include所有其它自动生成的xsd文件
            foreach (var item in _xsdFiles)
            {
                xsdFile.Imports.Add(new XElement(
                    _xs + "include",
                    new XAttribute("schemaLocation", item.Key + ".xsd")
                    ));
            }
            //添加dll中所有定义的element
            foreach (var item in _elements)
            {
                xsdFile.Elements.Add(item);
            }
            return xsdFile;
        }

        private void AddProperties(Type type, XElement sequenceElement)
        {
            var properties = type.GetProperties();
            foreach (var propertyInfo in properties)
            {
                var typeName = Common.GetXsdTypeName(propertyInfo.PropertyType);
                var propertyElement = new XElement(
                    _xs + "element",
                    new XAttribute("name", propertyInfo.Name),
                    new XAttribute("type", typeName)
                    );

                var xsdElement = XsdElement.Get(propertyInfo);
                if (xsdElement != null)
                {
                    if (!string.IsNullOrEmpty(xsdElement.MinOccurs))
                        propertyElement.SetAttributeValue("minOccurs", xsdElement.MinOccurs);
                    if (!string.IsNullOrEmpty(xsdElement.MaxOccurs))
                        propertyElement.SetAttributeValue("maxOccurs", xsdElement.MaxOccurs);

                    if (!string.IsNullOrEmpty(xsdElement.Annotation))
                        propertyElement.Add(new XElement(
                            _xs + "annotation",
                            new XElement(
                                _xs + "documentation", xsdElement.Annotation
                                )
                            ));
                }

                //判断是否自定义类型, 添加Import
                if (!typeName.StartsWith("xs:"))
                {
                    var parentClassFileGroup = XsdComplexType.Get(type).FileGroup;
                    var propertyClassFileGroup = Common.GetFileGroup(propertyInfo.PropertyType);
                    if (parentClassFileGroup != propertyClassFileGroup)
                    {
                        string importXsd = propertyClassFileGroup + ".xsd";
                        //判断是否已经存在该Import
                        if (_xsdFiles[parentClassFileGroup].Imports.All(item => item.Attribute("schemaLocation").Value != importXsd))
                        {
                            _xsdFiles[parentClassFileGroup].Imports.Add(
                                new XElement(
                                    _xs + "include",
                                    new XAttribute("schemaLocation", importXsd)
                                    )
                                );
                        }
                    }
                }
                sequenceElement.Add(propertyElement);
            }
        }

        private XElement BuildSimpleType(Type type, out string fileGroup)
        {
            var xsdSimpleType = XsdSimpleType.Get(type);
            //添加XSD文件
            fileGroup = xsdSimpleType.FileGroup;
            SetDefaultFile(fileGroup);

            var simpleTypeElement = new XElement(
                _xs + "simpleType",
                new XAttribute("name", type.Name),
                new XAttribute("final", "restriction")
                );
            var restrictionElement = new XElement(
                _xs + "restriction",
                new XAttribute("base", "xs:string")
                );

            foreach (var val in Enum.GetNames(type))
            {
                restrictionElement.Add(
                    new XElement(
                        _xs + "enumeration",
                        new XAttribute("value", val)
                        )
                    );
            }
            simpleTypeElement.Add(restrictionElement);
            return simpleTypeElement;
        }

        private void SetDefaultFile(string fileGroup)
        {
            if (!_xsdFiles.ContainsKey(fileGroup))
            {
                var xsdFile = new XsdFile();
                _xsdFiles[fileGroup] = xsdFile;
            }
        }
    }
}

XsdBuilder依次反射出Assembly、Class、Enum、Property的自定义Attribute,根据XSD的规则构造XElement。主要步骤在Builder函数中都有所体现。

应用

现在写接口契约就很爽了,只要定义好类生成DLL,通过XsdGen.exe就可轻松生成接口契约

参考

http://www.codeproject.com/Articles/2933/Attributes-in-C

https://msdn.microsoft.com/en-us/library/84c42s56%28v=vs.110%29.aspx

https://msdn.microsoft.com/en-us/library/aa719879(v=vs.71).aspx

https://msdn.microsoft.com/en-us/library/y1375e30%28v=vs.110%29.aspx

http://stackoverflow.com/questions/3353699/using-reflection-to-get-all-classes-of-certain-base-type-in-dll

http://stackoverflow.com/questions/1936953/custom-assembly-attributes

http://stackoverflow.com/questions/1168532/xsd-definition-for-enumerated-value

https://msdn.microsoft.com/en-us/library/bb387075.aspx

时间: 2024-10-16 08:23:42

XsdGen:通过自定义Attribute与反射自动生成XSD的相关文章

利用Vistual Studio自带的xsd.exe工具,根据XML自动生成XSD

利用Vistual Studio自带的xsd.exe工具,根据XML自动生成XSD 1, 命令提示符-->找到vs自带的xsd.exe工具所在的文件夹 例如: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin 注意:win7操作系统“命令提示符”要以管理员身份运行 2,将Xml文件拷贝到xsd.exe工具所在的文件夹,生成的xsd文件也将在这个文件夹中 3,在命令提示符中输入 xsd.exe test.xml, 多个xml文件以空格隔

根据XML自动生成XSD

利用Vistual Studio自带的xsd.exe工具,根据XML自动生成XSD 1, 命令提示符-->找到vs自带的xsd.exe工具所在的文件夹 例如: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin 注意:win7操作系统"命令提示符"要以管理员身份运行 2,将Xml文件拷贝到xsd.exe工具所在的文件夹,生成的xsd文件也将在这个文件夹中 3,在命令提示符中输入 xsd.exe test.xml, 多个x

wpf 通过为DataGrid所绑定的数据源类型的属性设置Attribute改变DataGrid自动生成列的顺序

环境Win10 VS2019 .Net Framework4.8 在wpf中,如果为一个DataGrid绑定到一个数据源,默认情况下DataGrid会为数据源类型的每个属性生成一个列(Column)对象.但并没有简单的方式用来控制列的生成顺序. DataGrid提供了两个与自动生成列有关的事件,分别是: AutoGeneratingColumn 会在为每个属性创建列时引发,引发时列已经创建完毕,在这个事件中可以: 通过e.Column获取已经创建的列对象,并对其进行修改. 通过将e.Cancel

如何由XSD自动生成XML和实体类

项目中有时候要用XML作为数据源,因此需要定义XML文件和相应的类,最佳方法是首先定义XSD,然后自动生成实体类,最后生成XML和填充数据:读取XML数据源的时候,首先用XSD验证XML数据格式,然后自动读入实体类使用. 定义XSD的过程就是类似设计表结构的过程,二者也可以相互转化. 本文讨论了如何定义XSD文件(XML Schema),然后自动生成实体类,最后生成XML的过程,以及如何根据XSD验证XML文件的合法性.以供大家做项目时参考. 1. 首先在VS2005中添加一个XSD文件.例子X

[goa]golang微服务框架学习(二)-- 代码自动生成

之前用过go语言的反射来做一些代码生成,参考这篇. 但是这种方式,入侵太强,需要执行对应的申明调用, 所以对GOA框架的自动生成非常感兴趣,于是仔细研究了一下,发现用的比较巧妙, 这里先卖个关子,先看看生成的代码目录结构. 这里使用adder的desgin文件来生成: package design import ( . "github.com/goadesign/goa/design" . "github.com/goadesign/goa/design/apidsl&quo

自动生成构造方法、getter、setter

利用反射自动生成getter.setter.constructor 写个模板类 package common; public class Templates { public static final String T_CLASS = "package {0};\n\n{1}public class {2} {\n\n{3}\n\n{5}\n\n{4}\n}"; public static final String T_GET = "\tpublic {0} get{1} (

mybatis自定义代码生成器(Generator)——自动生成model&amp;dao代码

花了两天的时间研究了下mybatis的generator大体了解了其生成原理以及实现过程.感觉generator做的非常不错,给开发者也留足了空间.看完之后在generator的基础上实现了自定义的生成器.代码start..... 建立了一个maven工程(common)项目结构: ----------------------------------------------------------------pom.xml-------------------------------------

自定义博客园主题和自动生成目录

背景 最近觉得博客园网站太老旧了,不好看,并且没有移动端,于是想转到简书去写博客(主要简书有移动端),写出来的效果还是不满意,于是又回到了博客园,只能自己修改下博客主题了. 于是百度了下,找到了两篇参考博客: 主题修改参考了:一套简约漂亮的响应式博客园主题皮肤 添加目录参考了:让博客园博客自动生成章节目录索引 在他们的基础上做了相应的修改,值得注意的一点是,主题修改必须注意当前所使用的默认模板是什么,如果不一样可能会造成样式错乱,因为我发现博客园不同的官方主题之间有的存在HTML结构的差异.我这

Hibernate使用自定义脚本替换注解或者xml文件中的自动生成表结构

本文作者:苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/50534361 我们都清楚,可以使用hibernate的metadata元数据生成表结构,但是一般情况下,我们光靠hibernate的自动生成是远远不够的,我们期待使用自己的sql脚本,你hibernate自动执行那个脚本就可以.那么hibernate支持不支持呢?答案是yes! 只需要我们做以下设置: <property name="hibernate.hb