【问题标题】:Convert XML to PSObject将 XML 转换为 PSObject
【发布时间】:2011-03-15 15:41:22
【问题描述】:

注意:我使用的是ConvertTo-XML,不能使用Export-Clixml

我创建了一个简单的PSObject:

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

然后我使用 ConvertTo-XML 将其转换为 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

【问题讨论】:

    标签: xml powershell


    【解决方案1】:

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

    filter XmlProperty([String]$Property) {
        $_.SelectSingleNode("/Objects/Object/Property[@Name='$Property']").InnerText
    }
    
    $Name = $b | Xmlproperty Name
    $Server = $b | XmlProperty Server
    # etc...
    

    编辑:一般来说,要对包含一个或多个 Object 元素的 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
    

    【讨论】:

    • 谢谢乔希。我想转换任何 PSObject,但这足以让我开始。我这样做是因为 PSObject 不支持 .NET 序列化。
    • 我更新了我的答案,以更通用的方式返回 PSObject。但是,它不是递归的,所以请记住这一点。
    【解决方案2】:

    我的无限深度变体。

    查看示例。

    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
        }
    }
    

    【讨论】:

    【解决方案3】:

    我通常将 xml 解析为哈希表,但使用从 here 获取的 convertto 函数我调整了该函数以转换为 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;  
            }
        } 
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-03
      • 1970-01-01
      • 2020-06-10
      • 2022-01-06
      • 2015-11-10
      • 1970-01-01
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多