2009-06-30 5 views
14

XMLからスケルトンXSDを生成することは可能です。たとえば、postには良い回答があります。いくつかのXMLからのXSDジェネレータ

質問は、複数の XMLに基づいてXSDを生成する方法です。その考え方は、各XMLがオプション、配列、選択肢などのいくつかの異なる出現を持つかもしれないということです。 これらの例から、最も正確なXSDを作成したいと思います。

私は衝突などがあるかもしれませんが、すべてのXMLが未知のXSDから来たと仮定して、理論的に可能でなければなりません。しかし、そのようなツールはありますか?

おかげ

答えて

14

Trangは注目すべきJames Clark氏によってで書かれたまさにそのようなツールです。 Relax NG標準とコンパクトな構文、古い学校のDTDとXMLスキーマなど、さまざまなXML定義の間で変換できます。また、1つ以上のxmlファイルからスキーマを推論することもできます。

あなたがubuntuを実行した場合、trangはユニバースリポジトリにパッケージ化されていますが、そのバージョンは少し壊れているようで、上のリンクからきれいにダウンロードするのが最適なオプションです。 trang.jarがカレントディレクトリにあるとします:

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

あなたが望むようにする必要があります。

+3

TrangのホームページはまだGoogleコードにリンクしていますが、プロジェクトはGithubに移動しました。将来それを見つけた他の人にとって、https://github.com/relaxng/jing-trangはTrangレポの新しい場所です。 – rmunn

+0

@ryanStull:例を挙げることはできますか?私はちょうど4つのxmlファイルの慎重に構築されたセットからTrangを使用してxsdを作ってきました。もう1つはfreeformatter.comを1つのファイルから使用しています。彼らは非常に異なっており、私は自分自身のバリデーションを追加するためにどの時間を使うべきかを決めるまでにはしばらく時間がかかるでしょう。 –

0

これは、1つの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を与えた場合、それはスキーマを強化する

4

の.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; 
     } 
    } 
} 
関連する問題