2013-03-13 6 views
11

Ich habe ein XML-Schema .xsd und erzeuge mit xsd.exe Werkzeug meine Datei mit allen C# Klassen. Wenn ich eine Sequenz von Elementen innerhalb eines XML-Tags habe, würde dies in C# mit einem Array dargestellt werden. Die FAIL ist offensichtlich. Wie kann ich Listen anstelle von Arrays generieren?wie man Liste anstelle von Array in C# mit xsd.exe erzeugt

Anstelle von Arrays fester Größe in einer Klasse möchte ich Listen verwenden.

Book [] books = new Book[someFixSize]; 

List<Book> books = new List<Book>(); 

Ich habe einige ältere (sehr alt) Fragen zu diesem Thema gesehen, aber keiner von ihnen eine erfüllte Lösung zu finden:/

Dies ist der neueste nützliche Hinweis: http://www.stefanbader.ch/xsdcsarr2l-exe-refactor-xsd-array-to-list/

Antwort

6

ich laufe in das gleiche Problem versucht, die svcutil zu verwenden, ohne die Verträge mit aus diesem Grund ich die xsdcsarr2l auch geschrieben l. Bei Interesse nehme ich mir Zeit und lade eine neuere Version hoch, in der zumindest die Listenvariablen automatisch initialisiert werden. Auf der anderen Seite ist das Projekt leicht genug, dass Sie die Quelle nehmen und selbst verbessern können, indem Sie die NRefactory-Klassen verwenden.

+0

Ersetzen Sie einfach die Zeile, die ein Array [] enthält, mit einer Liste ? Oder werden auch andere Zeilen des Codes bearbeitet? – Gero

+0

Nur die Zeilen, an denen die festen Arrays beteiligt sind. Das Tool analysiert die C# -Quelle und überträgt sie mit Hilfe von NRefactory in einen AST (Abstract Syntax Tree). So werden die Änderungen auf eine robuste Weise angewendet. Die Idee war, so wenig wie möglich vom Original zu berühren. – EvilBad

+0

Ja, laden Sie die neueste Version hoch. – Gero

2

Versuchen svcutil verwenden. exe

svcutil /o:myFile.cs /ct:System.Collections.Generic.List myXsd.xsd 
+1

Ich habe keine Datacontracts in meinem XSD, so svcutil nicht – Gero

+0

arbeiten werde ich Ihre einzige Option erraten ist manuell die automatische Code generiert Refactoring. – CathalMF

0

Versuchen Xsd2Code

Es Listen anstelle von Arrays erzeugt. Leider konnte ich meinen Code nicht deserialisieren, aber verglichen mit dem von xsd erzeugten Code sah er sehr ähnlich aus.

+0

nov2015 - xsd2code-Anbieter reagiert nicht mehr. Ich kann keine Testlizenz erhalten und die E-Mails prallen nicht ab. Ich denke, das ist aufgegeben. –

0

Ich lief in letzter Zeit das gleiche Problem, der einzige Grund, ich wollte Liste statt T [] war, weil ich Elemente zum Array hinzufügen wollte vor dem Senden einer Anfrage an einen Web-Service. Ich benutzte die Tatsache, dass xsd.exe eine partielle Klasse generiert. Sie können eine eigene partielle Klasse hinzufügen, indem Sie einen Konstruktor und eine ADDT-Methode hinzufügen, die Array.Resize() vor dem Zuweisen des (neuen) letzten Elements verwendet. Sie müssen den generierten Code nicht ändern oder ein anderes Tool verwenden.

0

Dan Field verfügt über eine powershell script, die eine Ausgabeklasse xsd.exe verwendet und ihre Arrays in generische Listen umwandelt. Das hat mit einer einfachen Klasse gut funktioniert, aber ich weiß nicht, wie gut es skaliert. Ich habe das folgende Skript eingefügt. Rufen Sie von einer Eingabeaufforderung wie folgt

"$(TargetFrameworkSDKToolsDirectory)xsd.exe" /c "$(ProjectDir)ImportedPartCanonical.xsd" "$(ProjectDir)ProjectCanonical.xsd" /n:Tallan.BT.PipelineComponents 

powershell.exe -ExecutionPolicy Unrestricted -file "$(solutiondir)\PowerShellScripts\PostProcessXsdExe.ps1" ProjectCanonical.cs "$(SolutionDir)Tallan.BT.PipelineComponents\SerializedClasses\ProjectCanonical.cs" 

Siehe den Link für die vollständige Erklärung.

# Author: Dan Field ([email protected]) 
# posted on blog.tallan.com/2016/03/10/xsd-exe-arrays-and-specified 
# Purpose: fix the 'specified' attribute and convert arrays to list from XSD.exe generated classes 

[CmdletBinding()] 
Param(
    [Parameter(Mandatory=$true,Position=1)] 
    [string]$inputFile, 
    [Parameter(Mandatory=$true,Position=2)] 
    [string]$outputFile, 
    [switch]$DeleteInputFile 
) 

# much faster than using Get-Content and/or Out-File/Set-Content 
$writer = [System.IO.StreamWriter] $outputFile 
$reader = [System.IO.StreamReader] $inputFile 

# used to track Specified properties 
$setterDict = @{} 

while (($line = $reader.ReadLine()) -ne $null) 
{ 
    $thisStart = $line.IndexOf("this.") # will be used for 
    $brackets = $line.IndexOf("[]") # indicates an array that will be converted to a Generic List 

    # assume that any private field that contains "Specified" needs to be grabbed 
    if (($line.IndexOf("private") -gt -1) -and ($line.IndexOf("Specified") -gt -1)) 
    { 
     # get the field name 
     $varName = $line.Split("{' ',';'}", [System.StringSplitOptions]::RemoveEmptyEntries)[-1] 
     # use field name as a key, minus the ending "Specified" portion, e.g. fieldNameSpecified -> fieldName 
     # the value in the dictionary will be added to setters on the main property, e.g. "this.fieldNameSpecified = true;" 
     $setterDict.Add($varName.Substring(0, $varName.IndexOf("Specified")), "this." + $varName + " = true;") 
     # output the line as is 
     $writer.WriteLine($line) 
    } 
    # find property setters that aren't for the *Specified properties 
    elseif (($thisStart -gt -1) -and ($line.IndexOf(" = value") -gt -1) -and ($line.IndexOf("Specified") -lt 0)) 
    { 
     # get the field name 
     $thisStart += 5 
     $varName = $line.Substring($thisStart, $line.IndexOf(' ', $thisStart) - $thisStart) 
     # see if there's a "Specified" property for this one 
     if ($setterDict.ContainsKey($varName) -eq $true) 
     { 
      # set the Specified property whenever this property is set 
      $writer.WriteLine((' ' * ($thisStart - 5)) + $setterDict[$varName]) 
     } 
     # output the line itself 
     $writer.WriteLine($line) 
    } 
    elseif ($brackets -gt 0) # change to List<T> 
    { 
     $lineParts = $line.Split(' ') 
     foreach ($linePart in $lineParts) 
     { 
      if ($linePart.Contains("[]") -eq $true) 
      { 
       $writer.Write("System.Collections.Generic.List<" + $linePart.Replace("[]", "> ")) 
      } 
      else 
      { 
       $writer.Write($linePart + " ") 
      } 
     } 
     $writer.WriteLine(); 
    } 
    else # just output the original line 
    { 
     $writer.WriteLine($line) 
    } 
} 

if ($DeleteInputFile -eq $true) 
{ 
    Remove-Item $inputFile 
}  

# Make sure the file gets fully written and clean up handles 
$writer.Flush(); 
$writer.Dispose(); 
$reader.Dispose(); 
Verwandte Themen