2010-07-14 62 views
16

注:我使用ConvertTo-XML而不能使用Export-Clixml转换XML到PSObject

我创建了一个简单的PSObjec吨:

$a = New-Object PSObject -Property @{ 
    Name='New' 
    Server = $null 
    Database = $null 
    UserName = $null 
    Password = $null 
} 

我然后将其转换成XML使用ConvertTo-XML

$b = $a | Convertto-XML -NoTypeInformation 

XML看起来像这样:

<?xml version="1.0"?> 
<Objects> 
    <Object> 
    <Property Name="Password" /> 
    <Property Name="Name">New</Property> 
    <Property Name="Server" /> 
    <Property Name="UserName" /> 
    <Property Name="Database" /> 
    </Object> 
</Objects> 

我很难找出点符号或XPath查询来提取属性/元素,并将$b转换回原始的PSObject

回答

13

您可以使用XPath轻松完成此操作。尽管PowerShell通常使用XML非常简单,但在这种情况下,我认为严格使用PowerShell语法的格式会非常糟糕。

filter XmlProperty([String]$Property) { 
    $_.SelectSingleNode("/Objects/Object/Property[@Name='$Property']").InnerText 
} 

$Name = $b | Xmlproperty Name 
$Server = $b | XmlProperty Server 
# etc... 

编辑:一般地做到这一点对于包含一个或多个对象元素的XML文档,你可以做这样的事情:

function ConvertFrom-Xml($XML) { 
    foreach ($Object in @($XML.Objects.Object)) { 
     $PSObject = New-Object PSObject 
     foreach ($Property in @($Object.Property)) { 
      $PSObject | Add-Member NoteProperty $Property.Name $Property.InnerText 
     } 
     $PSObject 
    } 
} 

ConvertFrom-Xml $b 
+0

感谢约什。我想转换任何PSObject,但这足以让我开始。我这样做是因为PSObject不支持.NET序列化。 – 2010-07-14 16:16:32

+0

我用更一般的方式回到PSObject来更新我的答案。但是,它不是递归的,所以记住这一点。 – Josh 2010-07-14 18:39:08

+0

不错!再次感谢。 – 2010-07-14 22:06:56

0

我与无限的深度变种。

查看示例。

function ConvertFrom-Xml { 
<# 
.SYNOPSIS 
    Converts XML object to PSObject representation for further ConvertTo-Json transformation 
.EXAMPLE 
    # JSON->XML 
    $xml = ConvertTo-Xml (get-content 1.json | ConvertFrom-Json) -Depth 4 -NoTypeInformation -as String 
.EXAMPLE 
    # XML->JSON 
    ConvertFrom-Xml ([xml]($xml)).Objects.Object | ConvertTo-Json 
#> 
    param([System.Xml.XmlElement]$Object) 

    if (($Object -ne $null) -and ($Object.Property -ne $null)) { 
     $PSObject = New-Object PSObject 

     foreach ($Property in @($Object.Property)) { 
      if ($Property.Property.Name -like 'Property') { 
       $PSObject | Add-Member NoteProperty $Property.Name ($Property.Property | % {ConvertFrom-Xml $_}) 
      } else { 
       if ($Property.'#text' -ne $null) { 
        $PSObject | Add-Member NoteProperty $Property.Name $Property.'#text' 
       } else { 
        if ($Property.Name -ne $null) { 
         $PSObject | Add-Member NoteProperty $Property.Name (ConvertFrom-Xml $Property) 
        } 
       } 
      } 
     } 
     $PSObject 
    } 
} 
0

我通常解析XML哈希表,但使用的ConvertTo功能我从here抓住我适应的功能转换为pscustom对象

function xmlNodeToPsCustomObject ($node){ 
    $hash = @{} 
    foreach($attribute in $node.attributes){ 
     $hash.$($attribute.name) = $attribute.Value 
    } 
    $childNodesList = ($node.childnodes | ?{$_ -ne $null}).LocalName 
    foreach($childnode in ($node.childnodes | ?{$_ -ne $null})){ 
     if(($childNodesList | ?{$_ -eq $childnode.LocalName}).count -gt 1){ 
      if(!($hash.$($childnode.LocalName))){ 
       $hash.$($childnode.LocalName) += @() 
      } 
      if ($childnode.'#text' -ne $null) { 
       $hash.$($childnode.LocalName) += $childnode.'#text' 
      } 
      $hash.$($childnode.LocalName) += xmlNodeToPsCustomObject($childnode) 
     }else{ 
      if ($childnode.'#text' -ne $null) { 
       $hash.$($childnode.LocalName) = $childnode.'#text' 
      }else{ 
       $hash.$($childnode.LocalName) = xmlNodeToPsCustomObject($childnode) 
      } 
     } 
    } 
    return $hash | ConvertTo-PsCustomObjectFromHashtable 
} 

function ConvertTo-PsCustomObjectFromHashtable { 
    param ( 
     [Parameter( 
      Position = 0, 
      Mandatory = $true, 
      ValueFromPipeline = $true, 
      ValueFromPipelineByPropertyName = $true 
     )] [object[]]$hashtable 
    ); 

    begin { $i = 0; } 

    process { 
     foreach ($myHashtable in $hashtable) { 
      if ($myHashtable.GetType().Name -eq 'hashtable') { 
       $output = New-Object -TypeName PsObject; 
       Add-Member -InputObject $output -MemberType ScriptMethod -Name AddNote -Value { 
        Add-Member -InputObject $this -MemberType NoteProperty -Name $args[0] -Value $args[1]; 
       }; 
       $myHashtable.Keys | Sort-Object | % { 
        $output.AddNote($_, $myHashtable.$_); 
       } 
       $output 
      } else { 
       Write-Warning "Index $i is not of type [hashtable]"; 
      } 
      $i += 1; 
     } 
    } 
}