注意:我正在使用
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
。
您可以使用 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
我的变体具有无限深度。
参见示例。
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
}
}
我通常将 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;
}
}
}