как создать список вместо массива в C# с помощью xsd.исполняемый

У меня есть XML-схема .xsd и генерировать с помощью xsd.инструмент exe моя файл со всеми классами c#. Если у меня есть последовательность элементов в XML-теге, она будет представлена в C# с массивом. The не - это очевидно. Как я могу генерировать списки вместо массивов?

вместо массивов фиксированного размера в классе я хотел бы использовать списки.

Book [] books = new Book[someFixSize];

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

Я видел некоторые старые (очень старые) вопросы по этому поводу, но ни один из них не предоставил удовлетворенное решение :/

Это последняя полезная подсказка:http://www.stefanbader.ch/xsdcsarr2l-exe-refactor-xsd-array-to-list/

5 ответов



попробуйте использовать svcutil.exe

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

поле Dan имеет сценарий powershell для этого требуется xsd.exe выводит класс и превращает его массивы в общие списки. Это хорошо сработало для меня с простым классом, но я не знаю, насколько хорошо он масштабируется. Я вставил сценарий ниже. Вызов из командной строки, как это

"$(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"

см. ссылку для полного объяснения.

# Author: Dan Field (dan.field@tallan.com)
# 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();

попробовать Xsd2Code

Он генерирует списки вместо массивов. К сожалению, я не смог заставить его десериализовать мой код, но, сравнивая его с кодом, сгенерированным xsd, он выглядел очень похожим.


недавно я столкнулся с той же проблемой, единственная причина, по которой я хотел список вместо T [], заключалась в том, что я хотел добавить элементы в массив перед отправкой запроса в веб-службу. Я использовал тот факт, что xsd.exe создает частичный класс. Вы можете добавить свой собственный частичный класс, добавив конструктор и метод ADDT, который будет использовать Array.Изменить размер () перед назначением (новому) последнему элементу. Нет необходимости изменять сгенерированный код или использовать другой инструмент.