2013-03-13 23 views
11

Tôi có lược đồ XML .xsd và tạo bằng công cụ xsd.exe tệp của tôi với tất cả các lớp C#. Nếu tôi có một chuỗi các phần tử trong một thẻ XML, thì nó sẽ được biểu diễn trong C# với một mảng. FAIL là hiển nhiên. Làm thế nào tôi có thể tạo danh sách thay vì mảng?cách tạo Danh sách thay vì Mảng trong C# bằng xsd.exe

Thay vì mảng kích thước cố định trong một lớp, tôi muốn sử dụng Danh sách.

Book [] books = new Book[someFixSize]; 

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

Tôi đã thấy một số câu hỏi cũ (rất cũ) về vấn đề này, nhưng không ai trong số họ cung cấp một giải pháp thỏa mãn:/

Đây là gợi ý hữu ích mới nhất: http://www.stefanbader.ch/xsdcsarr2l-exe-refactor-xsd-array-to-list/

Trả lời

6

tôi chạy vào cùng một vấn đề cố gắng sử dụng svcutil mà không có hợp đồng, vì lý do đó tôi đã viết xsdcsarr2l quá l. Nếu bạn quan tâm, tôi dành thời gian và tải lên phiên bản mới hơn nơi ít nhất các biến danh sách được khởi chạy tự động. Mặt khác, dự án này đủ nhẹ để bạn có thể lấy nguồn và tự cải thiện nó bằng cách sử dụng các lớp NRefactory.

+0

Bạn có đơn giản thay thế dòng có chứa một mảng [] với một danh sách ? Hoặc là bất kỳ dòng khác của mã chỉnh sửa quá? – Gero

+0

Chỉ các dòng trong đó các mảng cố định có liên quan. Công cụ này đang phân tích cú pháp C#-source và chuyển nó thành một AST (Abstract Syntax Tree) với sự trợ giúp của NRefactory. Vì vậy, những thay đổi được áp dụng một cách mạnh mẽ. Ý tưởng là để chạm vào càng ít càng tốt của bản gốc. – EvilBad

+0

vâng, tải lên phiên bản mới nhất. – Gero

2

Hãy thử sử dụng svcutil. exe

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

Tôi không có Datacontracts trong xsd, vì vậy svcutil sẽ không hoạt động – Gero

+0

Tôi đoán tùy chọn duy nhất của bạn là tự refactor mã được tạo tự động. – CathalMF

0

Hãy thử Xsd2Code

Tạo danh sách thay vì mảng. Thật không may tôi không thể làm cho nó để deserialize mã của tôi, nhưng so sánh nó với mã được tạo ra bởi xsd nó trông rất giống nhau.

+0

nov2015 - nhà cung cấp xsd2code hoàn toàn không phản hồi. Không thể nhận được giấy phép dùng thử và email bị trả lại. Tôi nghĩ rằng điều này bị bỏ rơi. –

0

Gần đây tôi gặp vấn đề tương tự, lý do duy nhất tôi muốn Danh sách thay vì T [] là vì tôi muốn Thêm mục vào mảng trước khi gửi yêu cầu đến dịch vụ web. Tôi đã sử dụng thực tế là xsd.exe tạo ra một lớp một phần. Bạn có thể thêm một lớp riêng của bạn thêm một hàm tạo và một phương thức ADDT sẽ sử dụng Array.Resize() trước khi gán cho phần tử cuối cùng (mới). Không cần thay đổi mã đã tạo hoặc sử dụng công cụ khác.

0

Trường Dan có powershell script có lớp đầu ra xsd.exe và biến các mảng của nó thành danh sách chung. Điều này đã làm việc tốt cho tôi với một lớp học đơn giản nhưng tôi không biết nó cân bằng như thế nào. Tôi đã dán tập lệnh bên dưới. Gọi từ dấu nhắc lệnh như thế này

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

Xem liên kết để được giải thích đầy đủ.

# 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(); 
Các vấn đề liên quan