Wednesday 21 February 2018

C# - XML - Inferring schemas for multiple Xml files

Summary:.NET library has a XmlSchemaInference class which allows the schema to be inferred from multiple Xml files.

So I wrote a program to answer a SO question a long time back and I have upgraded it here.

Whilst Visual Studio has a nice toolbar button to infer a schema from the xml file in view sometimes it is required to infer a schema from a clutch of given xml files and not just a single file. Currently I am working on an ebook creation help and a ebook (of the epub variety) has plenty of xml files and I would like to validate the xml files with a schema.


using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;

namespace XmlSchemaInferrer
{

    class Program
    {
        static void Main(string[] args)
        {
            string xsdFile = "";
            string[] xmlFiles = null;

            if (args.Length == 0)
            {
                Console.WriteLine("Please supply arg0, the output schema filename, and arg1, arg2 ... argn xml files the schema of which you want inferred...");
            }
            else
            {
                DivideArguments(args, ref xsdFile, ref xmlFiles);

                if (FilesExist(xmlFiles))
                {
                    Console.WriteLine("All files exist, good to infer...");
                    XmlSchemaSet schemaSet = new XmlSchemaSet();
                    XmlSchemaInference inference = new XmlSchemaInference();


                    bool bFirstTime = true;
                    foreach (string sFile in xmlFiles)
                    {
                        XmlReader reader = XmlReader.Create(sFile);
                        if (bFirstTime)
                        {
                            schemaSet = inference.InferSchema(reader);
                        }
                        else
                        {
                            schemaSet = inference.InferSchema(reader, schemaSet);
                        }
                        bFirstTime = false;
                    }


                    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings()
                    {
                        Indent = true,
                        IndentChars = "t"
                    };

                    XmlWriter writer = XmlWriter.Create(xsdFile, xmlWriterSettings);

                    foreach (XmlSchema schema in schemaSet.Schemas())
                    {

                        //schema.Write(Console.Out);
                        schema.Write(writer);
                    }
                    Console.WriteLine("Finished, wrote file to {0}...", xsdFile);
                    //Console.ReadLine();   
                }
            }

        }

        static void DivideArguments(string[] args, ref string xsdFile, ref string[] xmlFiles)
        {
            xsdFile = args[0];
            xmlFiles = new string[args.Length - 1];

            for (int i = 0; i < args.Length - 1; i++)
            {
                xmlFiles[i] = args[i + 1];
            }
        }

        static bool FilesExist(string[] args)
        {
            bool bFilesExist = true; //* until proven otherwise

            if (args.Length > 0)
            {
                foreach (string sFile in args)
                {
                    if (!File.Exists(sFile))
                        bFilesExist = false;
                }
            }
            return bFilesExist;
        }
    }
}


No comments:

Post a Comment