代码之家  ›  专栏  ›  技术社区  ›  Ariel

XmlSerializer在PowerShell中的功能?

  •  7
  • Ariel  · 技术社区  · 16 年前

    有没有一种方法可以利用PowerShell中.NET的XmlSerializer类的功能?

    更具体地说,能够轻松地将.NET类型反序列化为Xml,例如。

    XmlSerializer s = new XmlSerializer(typeof(MyType));
    TextReader r = new StreamReader("sample.xml");
    MyType myType = (MyType)s.Deserialize(r);
    r.Close();
    

    我知道我可以从PowerShell调用上面的代码,但是有没有办法避免在单独的程序集中定义MyType?谢谢

    1 回复  |  直到 16 年前
        1
  •  10
  •   Community Mohan Dere    9 年前

    当然,您可以在Powershell中定义一个类型,并在序列化中使用它。

    第一步是定义一个新类型。在 Powershell 2.0 ,你可以通过 打电话 Add-Type

    第2步是像平常一样使用XmlSerializer类——只需将问题中提供的C代码翻译成Powershell。

    下面的示例演示了。它定义一个简单类型,然后从XML字符串反序列化以创建该类型的新实例。然后打印出反序列化实例上的属性值。

    $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)
    

    感谢 Keith Hill 对于指向,请键入out。


    在Powershell 1.0中,您可以使用一些自定义代码执行类似的操作(请参见 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
        }
    }
    }
    

    $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)
    
    推荐文章