简体   繁体   English

如何使用xsd.exe在C#中生成List而不是Array

[英]how to generate List instead of Array in C# with xsd.exe

I have an XML schema .xsd and generate with xsd.exe tool my file with all the c# classes. 我有一个XML模式.xsd并使用xsd.exe工具生成我的文件和所有c#类。 If I have a sequence of elements within an XML tag, that would be represented in C# with an Array. 如果我在XML标记中有一系列元素,那么将在C#中用Array表示。 The FAIL is obvious. 失败是显而易见的。 How can I generate Lists instead of Arrays? 如何生成列表而不是数组?

Instead of fixed size arrays in a class, I would like to use Lists. 我想使用Lists而不是类中固定大小的数组。

Book [] books = new Book[someFixSize];

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

I have seen some older (very old) questions about this, but none of them provided a satisfied solution :/ 我已经看到了一些关于此问题的较旧(非常老)问题,但没有一个提供满意的解决方案:/

This is the latest useful hint: http://www.stefanbader.ch/xsdcsarr2l-exe-refactor-xsd-array-to-list/ 这是最新的有用提示: http//www.stefanbader.ch/xsdcsarr2l-exe-refactor-xsd-array-to-list/

I run into the same problem trying to use the svcutil without having the contracts, for that reason I wrote the xsdcsarr2l tool. 我遇到了同样的问题,试图在没有合同的情况下使用svcutil,因此我编写了xsdcsarr2l工具。 If you are interested I take the time and upload a newer version where at least the list variables are initialized automatically. 如果您有兴趣,我会花时间上传一个新版本,其中至少自动初始化列表变量。 On the other hand, the project is light enough, that you can take the source and improve it yourself by using the NRefactory classes. 另一方面,项目足够轻,您可以使用NRefactory类来获取源并自行改进。

尝试使用svcutil.exe

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

Dan Field has a powershell script that takes an xsd.exe output class and turns its arrays into generic lists. Dan Field有一个powershell脚本 ,它接受xsd.exe输出类并将其数组转换为通用列表。 This has worked well for me with a simple class but I don't know how well it scales. 这对我来说效果很好,只有一个简单的课程,但我不知道它有多好。 I've pasted the script below. 我已粘贴下面的脚本。 Call from a command prompt like this 从这样的命令提示符调用

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

See the link for full explanation. 请参阅链接以获取完整说明。

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

Try Xsd2Code 试试Xsd2Code

It generates lists instead of arrays. 它生成列表而不是数组。 Unfortunately I couldn't get it to deserialize my code, but comparing it to the code generated by xsd it looked very similar. 不幸的是我无法让它反序列化我的代码,但将它与xsd生成的代码进行比较看起来非常相似。

I ran into the same problem recently, the only reason I wanted List instead of T[] was because I wanted to Add items to the array before sending a request to a web service. 我最近遇到了同样的问题,我想要List而不是T []的唯一原因是因为我想在向Web服务发送请求之前将项添加到数组中。 I used the fact that xsd.exe generates a partial class. 我使用了xsd.exe生成分部类的事实。 You can add your own partial class adding a constructor and an ADDT method that will use Array.Resize() before assigning to the (new) last element. 您可以添加自己的部分类,添加构造函数和ADDT方法,该方法将在分配给(新)最后一个元素之前使用Array.Resize()。 No need to change the generated code or use another tool. 无需更改生成的代码或使用其他工具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM