如何从c#文件生成具有多个类定义的json模式

问题描述 投票:0回答:1

我试图从c#类文件中获取具有多个类的json模式。

我使用xsd.exe生成了c#类文件(* .cs文件)并提供了xml架构文件(xsd文件)(因为主xsd有2个导入所以,必须在xsd.exe命令的同一行中提供2个其他xsd文件)

即,使用xsd文件生成c#类文件的命令

C:\Users\user1\jsonschema>xsd.exe /c main_1.xsd imported_1.xsd xml.xsd /o:C:\Users\user1\jsonschema\output\
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 2.0.50727.3038]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file 'C:\Users\user1\jsonschema\output\main_1_xml.cs'.

在main_1_xml.cs文件中,我可以看到多个类定义,现在我需要将这个c#转换为json模式。我不知道该怎么做这部分。理想情况下,我正在寻找一个jsonschema outfile。

我承认我是新手c#所以,不太了解将c#类转换为json格式/模式的类/序列化或其他逻辑。

任何帮助非常感谢。

[编辑:根据佐哈尔的建议,包括更多细节]

基本上有xsd文件并使用xsd.exe生成c#类文件。此类文件具有多个子类/ paritial类定义。现在我试图将这个类定义变成json模式格式。

这里是c#类文件内容(有超过170个子/部分类定义,但简单只保留2:

using System.Xml.Serialization;
using System.Collections.Generic;
using Newtonsoft.Json;

// 
// This source code was auto-generated by xsd, Version=2.0.50727.3038.
// 

文件名:Program.cs

class Program // I have manually added this class and next line opening bracket for main class "Program"
{

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://example.org/content/")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="http://example.org/content/2018/", IsNullable=false)]
    public partial class newItem : AnyItemType {

        private ContentMetadataAfDType contentMetaField;

        private AssertType[] assertField;

        private inlineRef[] inlineRefField;

        private object[] items1Field;

        private contentSet contentSetField;

        /// <remarks/>
        public ContentMetadataAfDType contentMeta {
            get {
                return this.contentMetaField;
            }
            set {
                this.contentMetaField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("assert")]
        public AssertType[] assert {
            get {
                return this.assertField;
            }
            set {
                this.assertField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("inlineRef")]
        public inlineRef[] inlineRef {
            get {
                return this.inlineRefField;
            }
            set {
                this.inlineRefField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("derivedFrom", typeof(derivedFrom))]
        [System.Xml.Serialization.XmlElementAttribute("derivedFromValue", typeof(derivedFromValue))]
        public object[] Items1 {
            get {
                return this.items1Field;
            }
            set {
                this.items1Field = value;
            }
        }

        /// <remarks/>
        public contentSet contentSet {
            get {
                return this.contentSetField;
            }
            set {
                this.contentSetField = value;
            }
        }
    }
    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.example.org/content")]
    [System.Xml.Serialization.XmlRootAttribute("internal", Namespace="http://www.example.org/0809/content", IsNullable=false)]
    public partial class internalType {

        private object[] itemsField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("altId", typeof(altId), Namespace="http://example.org/content/2006-10-01/")]
        [System.Xml.Serialization.XmlElementAttribute("audience", typeof(AudienceType), Namespace="http://example.org/content/2006-10-01/")]
        [System.Xml.Serialization.XmlElementAttribute("contentMetaExtProperty", typeof(RSF_ContentMetaExtProperty_Flex2ExtPropType), Namespace="http://example.org/content/2006-10-01/")]
        [System.Xml.Serialization.XmlElementAttribute("itemMetaExtProperty", typeof(RSF_ItemMetaExtProperty_Flex2ExtPropType), Namespace="http://example.org/content/2006-10-01/")]
        [System.Xml.Serialization.XmlElementAttribute("subject", typeof(subject), Namespace="http://example.org/content/2006-10-01/")]
        public object[] Items {
            get {
                return this.itemsField;
            }
            set {
                this.itemsField = value;
            }
        }
    }
} // I have manually added this close bracket for main class "Program"

在同一个Program.cs文件中,我添加了一个类,并包含main方法和逻辑,以使用Newtonsoft生成json输出

class json
{
    /* below code to get the name of the classes from the namespace - was trying something
        public Type[] GetTypesInNamespace(Assembly assembly, string nameSpace)
        {
            return
              assembly.GetTypes()
                      .Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal))
                      .ToArray();
        }
    */
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Program Generation = new Program();
            var schemaGenerator = new Newtonsoft.Json.Schema.Generation.JSchemaGenerator();
            schemaGenerator.GenerationProviders.Add(new Newtonsoft.Json.Schema.Generation.StringEnumGenerationProvider());

            // if we give just main class name "Program, then in the out we get just 3 lines json format with type value as object"
            var schema = schemaGenerator.Generate(typeof(JsonSchema.Program));

            // if we pass-in main class and it's sub class name, then we get output of that sub class content as json format
            //var schema = schemaGenerator.Generate(typeof(JsonSchema.Program.newsItem));
            //Console.WriteLine(schema);

            File.WriteAllText(@"Program1.json", schema.ToString());

            //Program program = new Program();
            //string strResultJson = JsonConvert.SerializeObject(program);
            //File.WriteAllText(@"Program.json", strResultJson);
            //Console.WriteLine("Worked!");


        /*
            logic to get the sub classnames and loop through inorder to all sub classes content as single json schema in one file

            List<Type> theList = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.Namespace == "JsonSchema").ToList();
            Console.WriteLine(theList);
            //File.WriteAllText(@"Classnames.json", theList.ToString());
            for (int i = 0; i < theList.Count; i++)
            {
                Console.WriteLine(theList[i].Name); // this gives full list of class names

                File.WriteAllText(@"Classnames.json", theList[i].Name); // this writes only last classname, guess I need to figureout how to append
                //File.WriteAllLines(@"Classnames.json", i);
            }
        */

        }
    }
c# json xsd
1个回答
1
投票

这真的是一个非常简单的过程:

你创建了一个JSchemaGenerator的实例, (可选)将StringEnumGenerationProvider的新实例添加到它的GenerationProviders集合中, 并从c#type *生成模式:

var schemaGenerator = new Newtonsoft.Json.Schema.Generation.JSchemaGenerator();
schemaGenerator.GenerationProviders.Add(new Newtonsoft.Json.Schema.Generation.StringEnumGenerationProvider());
var schema = schemaGenerator.Generate(typeof(YourMainClassHere));

*不要忘记将YourMainClassHere更改为班级的实际名称。

这将生成主类的模式以及它的任何类型的属性。

更新 不要将所有xsd生成的类型包含在类中,而是尝试创建一个将所有这些类型用作属性的类:

class Program 
{
    public newItem NewItem { get; set; }
    public internalType InternalType { get; set; }
    public AssertType AssertType { get; set; }
    // Whatevet more types you need
}

然后,当您为Program类生成模式时,如果xsd生成类型,它还将包含所有属性。

© www.soinside.com 2019 - 2024. All rights reserved.