2009-06-30 16 views
14

Wiem, że możliwe jest generowanie szkieletu XSD z XML. Na przykład ten post ma dobre odpowiedzi.Generator XSD z kilku XML-ów

Pytanie brzmi, jak wygenerować XSD na podstawie kilku XML. Chodzi o to, że każdy XML może mieć kilka różnych wystąpień opcjonalnych, tablic, wyboru i tym podobnych. Ze wszystkich tych przykładów chciałbym skomponować najdokładniejszy XSD.

Wiem, że mogą wystąpić kolizje i tym podobne, ale zakładając, że cały kod XML pochodzi z nieznanego XSD, teoretycznie powinno to być możliwe. Ale czy istnieje takie narzędzie?

Dzięki

Odpowiedz

14

Trang jest właśnie takim narzędziem, napisany przez zauważalną w Jamesa Clarka. Może tłumaczyć różne formy definicji XML, takie jak normalna i zwarta składnia Relax NG, old-school DTD i schemat XML. Może także wnioskować o schemacie z jednego lub więcej plików XML.

Jeśli uruchomisz Ubuntu Trang jest spakowany w repozytorium wszechświata, ale ta wersja wydaje się nieco zepsuta, a czyste pobranie z powyższego linku jest prawdopodobnie najlepszą opcją. Zakładając, że plik trang.jar znajduje się w bieżącym katalogu:

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

powinien zrobić, co chcesz.

+3

Strona główna Trang nadal łączy się z Google Code, ale projekt został przeniesiony do Github. Dla każdego, kto znajdzie to w przyszłości, https://github.com/relaxng/jing-trang jest nową lokalizacją repo Trang. – rmunn

+0

@ryanStull: czy możesz podać przykład? Właśnie zrobiłem xsd za pomocą Trang z starannie skonstruowanego zestawu czterech plików xml, a drugiego za pomocą freeformatter.com z jednego pliku. są bardzo różne i minie trochę czasu, zanim będę miał czas, aby dowiedzieć się, który z nich zacznie dodawać moje własne walidacje. –

0

Jest to kod do tworzenia schematu z jednego XML: Przykładowy kod pokazujący, jak korzystać z tej klasy (zakłada, że ​​tam jest „XmlSchemaSet zestaw” członek klasy gromadzenia wyników i zawężania ich połączenia, aby połączyć):

 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(); 

Jeśli uruchomić go ponownie i dać XMLSchemaInference wygenerowany schemat i inny XML, zwiększy to schemat

4

.Net 4.5 ma schematu wnioskowania ...

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

może to akceptować wiele źródeł!

Potrzebowałem tego, więc napisałem kod, równie dobrze mogę współdzielić, przekazywać wiele ścieżek plików, pierwsza ścieżka to plik xsd, do którego napiszesz, a kolejne pliki są wejściowymi plikami Xml. To jest aplikacja konsolowa.

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; 
     } 
    } 
} 
0

To był link, którego szukałem. Pomyślałem, że podzielę się tym na wypadek, gdyby pomogło komuś innemu: