Chắc chắn, bạn có thể xác định loại trong Powershell và sử dụng nó trong tuần tự.
Bước đầu tiên là xác định loại mới. Trong Powershell 2.0, bạn có thể làm điều đó bằng cách gọi Add-Type. Một khi bạn có assembly được biên dịch động có chứa kiểu mới, bạn có thể sử dụng kiểu này một cách tự do, giống như bất kỳ loại .NET nào khác.
Bước 2 là chỉ sử dụng lớp XmlSerializer, như bạn thường làm - chỉ dịch mã C# mà bạn đã cung cấp trong câu hỏi cho Powershell.
Ví dụ sau minh họa. Nó định nghĩa một kiểu đơn giản, sau đó deserializes từ một chuỗi XML để tạo ra một thể hiện mới của kiểu đó. Sau đó nó in ra các giá trị thuộc tính trên trường hợp đã được tuần tự hóa.
$source1 = @"
using System;
using System.Xml;
using System.Xml.Serialization;
namespace MyDynamicTypes
{
[XmlRoot]
public class Foo
{
[XmlElement]
public string Message { get; set; }
[XmlAttribute]
public int Flavor { get; set; }
}
}
"@
Add-Type -TypeDefinition $source1 -Language "CSharpVersion3" -ReferencedAssemblies System.Xml.dll
$xml1 = @"
<Foo Flavor='19'>
<Message>Ephesians 5:11</Message>
</Foo>
"@
$f1 = New-Object MyDynamicTypes.Foo
$sr = New-Object System.IO.StringReader($xml1)
$s1 = New-Object System.Xml.Serialization.XmlSerializer($f1.GetType())
$xtr = New-Object System.Xml.XmlTextReader($sr)
$foo = $s1.Deserialize($xtr)
Write-Output ("foo.Flavor = " + $foo.Flavor)
Write-Output ("foo.Message = " + $foo.Message)
Nhờ Keith Hill để trỏ Thêm loại.
Trong Powershell 1.0, bạn có thể làm điều gì đó tương tự với một số mã tùy chỉnh (xem Powershell: compiling c# code stored in a string).
function Compile-Code {
param (
[string[]] $code = $(throw "The parameter -code is required.")
, [string[]] $references = @()
, [switch] $asString = $false
, [switch] $showOutput = $false
, [switch] $csharp = $true
, [switch] $vb = $false
)
$options = New-Object "System.Collections.Generic.Dictionary``2[System.String,System.String]";
$options.Add("CompilerVersion", "v3.5")
if ($vb) {
$provider = New-Object Microsoft.VisualBasic.VBCodeProvider $options
} else {
$provider = New-Object Microsoft.CSharp.CSharpCodeProvider $options
}
$parameters = New-Object System.CodeDom.Compiler.CompilerParameters
@("mscorlib.dll", "System.dll", "System.Core.dll", "System.Xml.dll", ([System.Reflection.Assembly]::GetAssembly([PSObject]).Location)) + $references | Sort -unique |% { $parameters.ReferencedAssemblies.Add($_) } | Out-Null
$parameters.GenerateExecutable = $false
$parameters.GenerateInMemory = !$asString
$parameters.CompilerOptions = "/optimize"
if ($asString) {
$parameters.OutputAssembly = [System.IO.Path]::GetTempFileName()
}
$results = $provider.CompileAssemblyFromSource($parameters, $code)
if ($results.Errors.Count -gt 0) {
if ($output) {
$results.Output |% { Write-Output $_ }
} else {
$results.Errors |% { Write-Error $_.ToString() }
}
} else {
if ($asString) {
$content = [System.IO.File]::ReadAllBytes($parameters.OutputAssembly)
$content = [Convert]::ToBase64String($content)
[System.IO.File]::Delete($parameters.OutputAssembly);
return $content
} else {
return $results.CompiledAssembly
}
}
}
Sử dụng chức năng đó, ứng dụng trở thành:
$source1 = @"
using System;
using System.Xml;
using System.Xml.Serialization;
namespace MyDynamicTypes
{
[XmlRoot]
public class Foo
{
[XmlElement]
public string Message { get; set; }
[XmlAttribute]
public int Flavor { get; set; }
}
}
"@
Compile-Code -csharp -code $source1
$xml1 = @"
<Foo Flavor='19'>
<Message>Ephesians 5:11</Message>
</Foo>
"@
$f1 = New-Object MyDynamicTypes.Foo
$sr = New-Object System.IO.StringReader($xml1)
$s1 = New-Object System.Xml.Serialization.XmlSerializer($f1.GetType())
$xtr = New-Object System.Xml.XmlTextReader($sr)
$foo = $s1.Deserialize($xtr)
Write-Output ("foo.Flavor = " + $foo.Flavor)
Write-Output ("foo.Message = " + $foo.Message)
Và nơi mà bạn sẽ mất 'MyType' từ nếu không phải từ một hội đồng? YOu không thể xác định trực tiếp các loại trong PowerShell; phải sử dụng 'Add-Type' cho điều đó. – Joey
Đó chính xác là câu hỏi của tôi - là có cách nào đó để xác định loại trong PowerShell, và sau đó vượt qua sử dụng nó cho serialization? Dựa trên câu trả lời của bạn, có vẻ như không, do đó phải xác định các loại trong một hội đồng ... Thật là một nỗi đau - Tôi muốn tạo ra một giải pháp dựa trên toàn bộ kịch bản cho một vấn đề mà không đòi hỏi phải lắp ráp et al. Cảm ơn. – Ariel
"là có một cách dễ dàng, như XmlSerializer, để sắp xếp các loại trong PowerShell" Import/Export-CliXml nên hoạt động tốt. – stej