Come sarebbe il design generale per un convertitore di classe XSD a C #?

6

Sto cercando di creare un semplice generatore di codice per convertire le definizioni XSD in classi C #. Questo è in parte un esercizio di apprendimento, ma vorrei anche ottenerne un uso pratico alla fine.

Che aspetto avrebbe la progettazione generale di un'applicazione del genere? Suppongo che avrò bisogno di usare uno dei parser XML nel framework .NET, ma quale? E quale sarà la struttura dati risultante? Sarà un albero delle espressioni?

Da lì, cosa succede? Genero codice concatenando le stringhe o esistono modi migliori e più sofisticati per farlo?

Importante: non cerco qualcuno che scriva codice per me (sebbene siano benvenuti campioni di codice molto brevi, se applicabili) e non ho bisogno che qualcuno faccia la ricerca per me. Sono perfettamente in grado di leggere me stesso su parser, alberi di espressione e generatori di codice. Ho solo bisogno di qualcuno che mi aiuti con le larghe pennellate, così da non entrare in troppi vicoli ciechi.

Sono anche a conoscenza di progetti open source come XSD2Code, ma preferirei fare il tentativo da solo, per motivi di apprendimento, e perché lo strumento risultante è probabilmente altamente specifico per il mio particolare scenario.

    
posta Robert Harvey 02.08.2013 - 07:00
fonte

4 risposte

3

What would the general design of such an application look like?

Lasciando da parte le trivalità come l'interfaccia utente, ti consigliamo di avere almeno tre parti principali:

  1. L'app "core", che traduce l'oggetto XML in una stringa C #.
  2. La parte che individua e legge il file XSD come XML e passa ogni oggetto all'app principale per l'elaborazione.
  3. La parte che scrive le stringhe C #.

Vuoi il # 1 per avere un bel po 'di ricorsione disponibile, dal momento che gli elementi XSD possono essere di tipi che contengono elementi, tipi ed elementi.

I assume that I will need to use one of the XML parsers in the .NET framework, but which one?

Carico l'intero XSD come un singolo System.XML.XMLDocument class, ma sono del web e ho imparato l'XML tramite DOM. È anche il modello precedente, e partire da cose come selectSingleNode è probabilmente meglio iniziare con interfacce che ottimizzano le prestazioni come XmlReader , o parser XML non-microsoft.

And what will the resulting data structure look like? Will it be an expression tree?

Perché non dovrebbe essere uno spazio dei nomi di strutture o classi?

From there, what happens? Do I generate code by concatenating strings, or are there better, more sophisticated ways to do it?

Non esistono modi migliori per generare stringhe da un programma rispetto alla concatenazione di stringhe. C'è solo zucchero sintattico per rendere il codice più facile da scrivere. Ma vuoi usare un System.Text.StringBuilder qui, invece di fare il mucking circa con il codice come segue:

string Line = new String();
Line = "public class " + xmlDoc.localName + "() {\n";
Line += "etc, etc.";
    
risposta data 02.08.2013 - 07:45
fonte
1

Algoritmo astratto

Transform (input)

Quando Trasforma viene chiamato con l'argomento input .

  1. Se input non è XML valido, riporta l'errore
  2. Lascia che xml sia il risultato della trasformazione di input in una rappresentazione astratta di XML
  3. Se xml non è conforme a XSD, riporta l'errore
  4. Lascia che CSharp sia il risultato della trasformazione di xml in una rappresentazione astratta del codice CSharp
  5. Lascia che output sia il risultato della trasformazione di CSharp in una stringa
  6. Restituisci output

C # Stub

public static string Transform(string input)
{
    var xml = ConvertStringToXml(input);    
    ValidateXsdSchemaConformance(xml);
    var csharp = ConvertXmlToCSharp(xml);
    return ConvertCSharpToString(csharp);
}
    
risposta data 02.08.2013 - 08:06
fonte
1

Le persone usano gli AST fondamentalmente perché un algoritmo di analisi generale (come un generatore di parser potrebbe impiegare) non può fare di meglio, non perché un AST è un modello semantico fantasticamente conveniente.

Nel tuo caso, altre persone hanno convenientemente scritto sia un parser che un grado base di un modello semantico come parte dell'attuazione del parser XML. Quindi sicuramente vuoi iniziare da lì.

Per me sembra che la decisione più importante sia se generare il codice direttamente dal DOM XML, o se creare il proprio modello semantico e popolarlo dal DOM, quindi generare il codice C # da lì. Il passaggio intermedio è più lavoro e più complessità, ma probabilmente si adatta meglio se si prevede di aggiungere un sacco di opzioni su esattamente ciò che viene generato il codice. Suppongo che in teoria il passaggio intermedio renderebbe un po 'più semplice supportare un formato diverso da XSD, ma sembra un caso d'uso inverosimile.

Per quanto riguarda cosa usare per generare il codice, ho provato a utilizzare le classi System.CodeDom per creare codice in modo programmatico in modo indipendente dalla sintassi - e lo odiavo. Per la maggior parte delle situazioni è lontano più facile costruire una stringa di codice e basta dirgli di compilare la stringa. Posso immaginare una situazione in cui il codice di generazione del codice fosse necessario per apportare modifiche che hanno causato effetti a catena su tutta la stringa che stavi generando al punto in cui costruire una stringa era il percorso più difficile, ma non l'ho mai incontrato - e mi piace usare il codice generazione.

    
risposta data 20.09.2013 - 19:33
fonte
0

AIUI, gli alberi di espressione servono per la manipolazione interna di una singola funzione lambda, non per rappresentare un'intera classe. Per la rappresentazione intermedia di produrre metà del disegno le opzioni principali sono un AST personalizzato e una concatenazione di stringhe (come suggerito in un'altra risposta) o CodeDOM . Quest'ultimo è piuttosto dettagliato ma ti darebbe flessibilità se decidessi di voler emettere VB, JS o qualsiasi altra cosa Microsoft scelga di aggiungere in futuro.

In fondo è il vecchio compromesso tra KISS e enterprisy.

    
risposta data 02.08.2013 - 10:36
fonte

Leggi altre domande sui tag