Convertir XML en PSObject
Note: j'utilise ConvertTo-XML
et ne peut pas utiliser Export-Clixml
:
j'ai créer un simple PSObjec
t:
$a = New-Object PSObject -Property @{
Name='New'
Server = $null
Database = $null
UserName = $null
Password = $null
}
je le convertis alors en XML en utilisant ConvertTo-XML
:
$b = $a | Convertto-XML -NoTypeInformation
le XML ressemble à ceci:
<?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>
j'ai du mal à trouver la notation de points ou la requête XPath pour extraire les attributs/éléments et convertir $b
retour à l'original PSObject
.
3 réponses
Vous pouvez le faire assez facilement avec XPath. Bien que PowerShell rend généralement travailler avec XML assez simple, dans ce cas, je pense que le format utilisant strictement la syntaxe PowerShell serait assez grossier.
filter XmlProperty([String]$Property) {
$_.SelectSingleNode("/Objects/Object/Property[@Name='$Property']").InnerText
}
$Name = $b | Xmlproperty Name
$Server = $b | XmlProperty Server
# etc...
EDIT: le terme générique le faire pour un document XML qui contient un ou plusieurs éléments d'Objet, vous pouvez faire quelque chose comme ceci:
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
ma variante avec une profondeur illimitée.
voir exemples.
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
}
}
j'utilise habituellement xml pour hacher les tables mais en utilisant la fonction convertto j'ai saisi à partir de ici j'ai adapté la fonction pour convertir en objets 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;
}
}
}