Генератор XSD из нескольких XML файлов

Я знаю, что можно генерировать скелет XSD из XML. Например, этот пост имеет хорошие ответы.

Вопрос заключается в том, как генерировать XSD на основе нескольких XML. Идея состоит в том, что каждый XML может иметь несколько различных вариантов необязательных, массивов, выбора и тому подобного. Из всех этих примеров я хотел бы составить наиболее точный XSD.

Я знаю, что могут быть столкновения и т.д., но, предполагая, что весь XML появился из XND, он должен быть теоретически возможным. Но есть ли такой инструмент?

Спасибо

Ответы

Ответ 1

Trang - вот такой инструмент, написанный известным Джеймсом Кларком. Он может переводить между различными формами определений xml, такими как нормальный и компактный синтаксис Relax NG, старая DTD школы и XML-схема. Он также может вывести схему из одного или нескольких файлов xml.

Если вы запустите ubuntu trang, он упакован в репозиторий юниверса, но эта версия кажется немного сломанной, и чистая загрузка с указанной выше ссылки, вероятно, является вашим лучшим вариантом. Предполагая, что trang.jar находится в текущем каталоге:

java -jar trang.jar -I xml -O xsd file1.xml file2.xml definition.xsd

должен делать то, что вы хотите.

Ответ 2

.Net 4.5 имеет вывод схемы...

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

это может принимать несколько источников!

Мне это нужно, поэтому я написал код, также могу поделиться, передать несколько путей к файлам, первый путь к файлу - это файл xsd, который вы будете писать, а последующие файлы - это входные файлы Xml. Это консольное приложение.

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

namespace SchemaInferrer
{
    class Program
    {
        static void Main(string[] args)
        {
            string xsdFile="";
            string[] xmlFiles=null;
            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;
        }
    }
}

Ответ 3

Это код для создания схемы из одного XML: Пример кода, демонстрирующий, как использовать этот класс (он предполагает, что есть член класса "XmlSchemaSet set", накапливающий результаты и уточняющий их от вызова к вызову):

        var si = new XmlSchemaInference();
        var reader = XmlReader.Create(new StringReader(textBox1.Text));
        var en = si.InferSchema(reader, set).Schemas().GetEnumerator();
        en.MoveNext();
        var schema = en.Current as XmlSchema;
        var stream = new MemoryStream();
        if (schema != null)
        {
            schema.Write(stream);
            set.Add(schema);
        }
        stream.Flush();
        stream.Position = 0;
        var streamReader = new StreamReader(stream);
        var str = streamReader.ReadToEnd();
        grid1.Model.LoadSchema(str);
        reader.Close();
        stream.Close();
        streamReader.Close();

Если вы запустите его снова и предоставите XMLSchemaInference сгенерированную схему и другой XML, это улучшит схему