如何在c#中使用xsd.exe生成列表而不是数组
本文关键字:列表 数组 exe xsd | 更新日期: 2023-09-27 18:03:39
我有一个XML模式。xsd文件,并使用xsd.exe工具用所有c#类生成我的文件。如果我在XML标记中有一个元素序列,那么它将在c#中用数组表示。失败很明显。如何生成列表而不是数组?
我想用列表代替类中固定大小的数组。
Book [] books = new Book[someFixSize];
List<Book> books = new List<Book>();
我看过一些关于这个的老问题,但是没有一个提供一个满意的解决方案:/
这是最新的有用提示:http://www.stefanbader.ch/xsdcsarr2l-exe-refactor-xsd-array-to-list/
我在没有合约的情况下尝试使用svcutil时遇到了同样的问题,因此我编写了xsdcsarr2l工具。如果您感兴趣,我花时间上传一个更新的版本,其中至少列表变量是自动初始化的。另一方面,这个项目很轻,你可以使用NRefactory类来获取源代码并自己改进它。
尝试使用svcutil.exe
svcutil /o:myFile.cs /ct:System.Collections.Generic.List myXsd.xsd
Dan Field有一个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 the 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生成的代码进行比较,它看起来非常相似。
我最近遇到了同样的问题。我想要list的唯一原因是而不是T[]是因为我想在向web服务发送请求之前将项添加到数组中。
我使用了xsd.exe生成部分类的事实。您可以添加自己的分部类,添加一个构造函数和一个ADDT方法,该方法将在赋值给(new)最后一个元素之前使用Array.Resize
不需要更改生成的代码或使用其他工具