2013-03-13 6 views
11

XML 스키마가 xsd이고 xsd.exe 도구으로 모든 파일을 생성합니다. # 클래스. XML 태그 내에 일련의 요소가있는 경우 Array가있는 C#으로 표현됩니다. FAIL은 분명합니다. 배열 대신리스트를 생성하려면 어떻게해야합니까?xsd.exe를 사용하여 C#에서 배열 대신 List를 생성하는 방법

클래스의 고정 크기 배열 대신 목록을 사용하고 싶습니다.

Book [] books = new Book[someFixSize]; 

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

나는 이것에 대해 일부 이전 (아주 오래된) 질문을 봐 왔지만, 그들 중 누구도 만족 솔루션을 제공하지 : http://www.stefanbader.ch/xsdcsarr2l-exe-refactor-xsd-array-to-list/

답변

6

내가는 svcutil를 사용하려고 같은 문제로 실행 엘. 관심이 있으시면 적어도 시간이 걸리고 목록 변수가 자동으로 초기화되는 최신 버전을 업로드하십시오. 반면에 프로젝트는 충분히 가볍기 때문에 NRefactory 클래스를 사용하여 소스를 가져 와서 직접 개선 할 수 있습니다.

+0

Array []가 포함 된 줄을 List 으로 간단하게 바꿀 수 있습니까? 아니면 편집 된 코드의 다른 줄도 있습니까? – Gero

+0

고정 배열이 포함 된 라인 만. 이 도구는 C# -source를 파싱하고 NRefactory를 사용하여 AST (Abstract Syntax Tree)로 전송합니다. 따라서 변경 사항은 강력한 방식으로 적용됩니다. 아이디어는 가능한 한 적은 수의 원본을 만지는 것이 었습니다. – EvilBad

+0

예, 최신 버전을 업로드하십시오. – Gero

2

는 svcutil를 사용해보십시오 :이 최신 유용한 힌트/

합니다. 내가 너무 xsdcsarr2l을 쓴 이유로 계약을하지 않고 EXE

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

내 xsd에는 Datacontracts가 없으므로 svcutil이 작동하지 않습니다. – Gero

+0

유일한 옵션은 수동으로 생성 된 자동 생성 코드입니다. – CathalMF

0

Xsd2Code

그것은 대신 배열의 목록을 생성하십시오. 불행히도 내 코드를 deserialize 할 수는 없지만 xsd에서 생성 된 코드와 비교하면 매우 비슷해 보입니다.

+0

nov2015 - xsd2code 공급 업체가 완전히 응답하지 않습니다. 평가판 라이센스 및 이메일 반송을받을 수 없습니다. 나는 이것이 버려진 것 같아. –

0

나는 웹 서비스에 요청을 보내기 전에 배열에 항목을 추가하기를 원했기 때문에 T [] 대신 List를 원했다는 유일한 이유가 최근에 같은 문제에 부딪쳤다. xsd.exe가 부분 클래스를 생성한다는 사실을 사용했습니다. 자신 만의 부분 클래스를 추가하여 생성자를 추가하고 (new) 마지막 요소에 할당하기 전에 Array.Resize()를 사용할 ADDT 메서드를 추가 할 수 있습니다. 생성 된 코드를 변경하거나 다른 도구를 사용할 필요가 없습니다.

0

Dan Field는이며 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 ([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();