将 XML 转换为 PSObject
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3242995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert XML to PSObject
提问by Chad Miller
Note: I'm using ConvertTo-XMLand cannot use Export-Clixml:
注意:我正在使用ConvertTo-XML并且不能使用Export-Clixml:
I create a simple PSObject:
我创建了一个简单的PSObject:
$a = New-Object PSObject -Property @{
Name='New'
Server = $null
Database = $null
UserName = $null
Password = $null
}
I then convert it into XML using ConvertTo-XML:
然后我使用ConvertTo-XML以下方法将其转换为 XML :
$b = $a | Convertto-XML -NoTypeInformation
The XML looks like this:
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>
I'm having trouble figuring out the dot notation or XPath query to extract the attributes/elements and convert $bback to the original PSObject.
我无法弄清楚点符号或 XPath 查询来提取属性/元素并将其转换$b回原始PSObject.
采纳答案by Josh
You can do this pretty easily with XPath. Although PowerShell usually makes working with XML pretty simple, in this case I think the format using strictly PowerShell syntax would be pretty gross.
使用 XPath 可以很容易地做到这一点。尽管 PowerShell 通常使处理 XML 变得非常简单,但在这种情况下,我认为使用严格的 PowerShell 语法的格式会非常粗糙。
filter XmlProperty([String]$Property) {
$_.SelectSingleNode("/Objects/Object/Property[@Name='$Property']").InnerText
}
$Name = $b | Xmlproperty Name
$Server = $b | XmlProperty Server
# etc...
EDIT: To generically do this for an XML document that contains one or more Object elements, you can do something like this:
编辑:要对包含一个或多个 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
回答by Sergey Mukhin
My variant with unlimited depth.
我的变体具有无限深度。
See examples.
请参阅示例。
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
}
}
回答by Drundage
I usually parse xml to hash tables but using the convertto function I grabbed from hereI adapted the function to convert to pscustom objects
我通常将 xml 解析为哈希表,但使用我从这里抓取的 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;
}
}
}

