Powershell 将数据/值列表转换为对象属性

Powershell 将数据/值列表转换为对象属性,powershell,Powershell,我有一个嵌套字典样式数组,如这里的$Events,其中有一列属性名和一列值: PS > $Events[0].EventProperties Name #text ------- ------- EventName ItBroke Category Bad When 2020 作为参考,我使用的这种数据通常来自类似于这样的xml,所以也许我可以更好地处理它: <Events> <EventProperties Name="Eve

我有一个嵌套字典样式数组,如这里的
$Events
,其中有一列属性名和一列值:

PS > $Events[0].EventProperties

Name      #text
-------   -------
EventName ItBroke
Category  Bad
When      2020
作为参考,我使用的这种数据通常来自类似于这样的xml,所以也许我可以更好地处理它:

<Events>
  <EventProperties Name="EventName">ItBroke</EventProperties>
  <EventProperties Name="Category">Bad</EventProperties>
  <EventProperties Name="When">2020</EventProperties>
</Events>
<Events ... />

我会用我目前的方式来回答这个问题,但是它速度很慢,伸缩性很差,所以我正在寻求帮助来更好地构建它。感觉很简单,我不知道自己能找到的正确术语。

我知道的唯一方法是单独创建对象,然后通过双
ForEach
循环将数据中的成员属性添加到对象中

$EventData=@()                           # Create empty list object
# Iterate through events
Foreach ($event in $Events) {            # Iterate through events
    $object = New-Object PSObject        # Create new object for event data
    $event.EventProperties | Foreach {   # Iterate through data, and create new member properties
        Add-Member -InputObject $object `
            -MemberType NoteProperty `
            -name $_.Name `
            -Value $_.'#text'
    }
    $EventData += $object                # Add new object to result list
}
$EventData                               # Output result, matches example from question

这是缓慢的,但动态性足够好,不必担心每个事件有多少属性/是否存在所有属性。

我知道的唯一方法是单独创建对象,然后通过双
ForEach
循环将数据中的成员属性添加到对象中

$EventData=@()                           # Create empty list object
# Iterate through events
Foreach ($event in $Events) {            # Iterate through events
    $object = New-Object PSObject        # Create new object for event data
    $event.EventProperties | Foreach {   # Iterate through data, and create new member properties
        Add-Member -InputObject $object `
            -MemberType NoteProperty `
            -name $_.Name `
            -Value $_.'#text'
    }
    $EventData += $object                # Add new object to result list
}
$EventData                               # Output result, matches example from question

这是慢的,但足够动态,不必担心每个事件有多少属性/是否存在所有属性。

您可以使用哈希表存储属性/值数据,将这些哈希表转换为自定义对象,从而优化您已经完成的工作,然后避免使用低效的
+=
来扩展数组

$EventData = $Events | Foreach-Object {
    $hash = [ordered]@{}
    $_.EventProperties | Foreach-Object {
        $hash[$_.Name] = $_.innertext
    }
    [pscustomobject]$hash
}
$EventData

您可以查看PosikS壳7并考虑<代码>前缀对象-并行< /代码>,如果您有很多<代码>事件属性节点。

所有循环都是必需的,因为您希望将属性名称转换为属性。
[xml]
加速器将元素(节点)名称转换为属性。我相信这种行为对于PowerShell中的其他XML反序列化程序来说是典型的


如果将XML重新构造为将这些属性名称改为元素名称,则只需要将XML转换为对象:

# sample x.xml
<root>
<Events>
  <EventProperties>
    <EventName>ItBroke</EventName>
    <Category>Bad</Category>
    <When>2020</When>
  </EventProperties>
</Events>
<Events>
  <EventProperties>
    <EventName>ItBroke</EventName>
    <Category>Bad</Category>
    <When>2020</When>
  </EventProperties>
</Events>
</root>

# Conversion Code
$x = [xml](Get-Content x.xml)
$x.Root.Events.EventProperties

# Output
EventName Category When
--------- -------- ----
ItBroke   Bad      2020
ItBroke   Bad      2020
#示例x.xml
它坏了
坏的
2020
它坏了
坏的
2020
#转换码
$x=[xml](获取Content x.xml)
$x.Root.Events.EventProperties
#输出
事件名称类别
--------- -------- ----
它在2020年坏了
它在2020年坏了

通过使用哈希表存储属性/值数据,将这些哈希表转换为自定义对象,然后避免使用低效的
+=
来扩展数组,您可以优化已经完成的工作

$EventData = $Events | Foreach-Object {
    $hash = [ordered]@{}
    $_.EventProperties | Foreach-Object {
        $hash[$_.Name] = $_.innertext
    }
    [pscustomobject]$hash
}
$EventData

您可以查看PosikS壳7并考虑<代码>前缀对象-并行< /代码>,如果您有很多<代码>事件属性节点。

所有循环都是必需的,因为您希望将属性名称转换为属性。
[xml]
加速器将元素(节点)名称转换为属性。我相信这种行为对于PowerShell中的其他XML反序列化程序来说是典型的


如果将XML重新构造为将这些属性名称改为元素名称,则只需要将XML转换为对象:

# sample x.xml
<root>
<Events>
  <EventProperties>
    <EventName>ItBroke</EventName>
    <Category>Bad</Category>
    <When>2020</When>
  </EventProperties>
</Events>
<Events>
  <EventProperties>
    <EventName>ItBroke</EventName>
    <Category>Bad</Category>
    <When>2020</When>
  </EventProperties>
</Events>
</root>

# Conversion Code
$x = [xml](Get-Content x.xml)
$x.Root.Events.EventProperties

# Output
EventName Category When
--------- -------- ----
ItBroke   Bad      2020
ItBroke   Bad      2020
#示例x.xml
它坏了
坏的
2020
它坏了
坏的
2020
#转换码
$x=[xml](获取Content x.xml)
$x.Root.Events.EventProperties
#输出
事件名称类别
--------- -------- ----
它在2020年坏了
它在2020年坏了

Awesome,使用
$hashtable[$newPropertyName]
的构造和到
[pscustomobject]
的转换对我来说都是新的,而且工作得很好!我确实希望数据的格式更好,但有时它不是。。。这对那些时候很有帮助:)太棒了,使用
$hashtable[$newPropertyName]
的构造和到
[pscustomobject]
的转换对我来说都是新的,而且工作得很好!我确实希望数据的格式更好,但有时它不是。。。这将有助于这些时间:)