gpt4 book ai didi

xml - 如何向 PSCustomObject 添加值(XML 到 CSV 的转换)

转载 作者:行者123 更新时间:2023-12-05 01:22:11 25 4
gpt4 key购买 nike

我正在尝试构建一个脚本来将 XML 文件转换为 CSV。我开始遵循本指南 https://learn.microsoft.com/en-us/answers/questions/542481/parse-xml-to-csv-help.html但我现在遇到以下情况:

我的代码的第一部分工作正常,它在第一列写入 CSV 文件,但是当它通过以下迭代时,即使将值输出到控制台,它也不会将值写入文件。这是我的代码:

[xml]$x = Get-Content C:\Users\Desktop\Policy.xml

$x.Profiles |
ForEach-Object{
$_.Profile |
ForEach-Object{
$_.Ruleset |
ForEach-Object{
Write-Host "Policy ID = " $_.ID
[PSCustomObject]@{
policyName = $_.ID
}
$_.Conditions |
ForEach-Object{
$_.condition |
ForEach-Object{
if($_.name -eq "Resource") {
Write-Host "Resource = " $_.'#text'
[PSCustomObject]@{
resource = $_.'#text'
}
}
if($_.name -eq "Action") {
Write-Host "Action = " $_.'#text'
[PSCustomObject]@{
action = $_.'#text'
}
}
if($_.name -eq "actor") {
Write-Host "actor = " $_.'#text'
[PSCustomObject]@{
actor = $_.'#text'
}
}
if($_.name -eq "child") {
Write-Host "child = " $_.'#text'
[PSCustomObject]@{
child = $_.'#text'
}
}
if($_.name -eq "number") {
Write-Host "number = " $_.'#text'
[PSCustomObject]@{
number = $_.'#text'
}
}
}
}
}
}
} | Export-Csv C:\Users\Desktop\policy.csv -NoTypeInformation

因此,直到第一个 [PSCustomObject](第 10 行)它工作正常并且 policyName 列被写入 CSV 值及其相应的值。但是在第二个 [PSCustomObject](第 19 行)应该写入 Resource/Action/actor/child/number 的地方,它不再写入文件。

将这些值添加到现有的 [PSCustomObject] 中的正确方法是什么?

供引用:

XML 片段

<?xml version="1.0" encoding="UTF-8"?>
<Profiles xmlns:pcrf="nothing interesting here">
<Profile Desc="some description" ID="someid" Prio="0">
<Ruleset Class="class1" Desc="" ID="policyid1" Prio="10" active="true">
<Conditions>
<condition name="Resource" type="matchExact">resource1</condition>
<condition name="Action" type="matchExact">action1</condition>
<condition name="actor" type="matchExact">actor1</condition>
</Conditions>
</Ruleset>
<Ruleset Class="classX" Desc="" ID="policyidX" Prio="10" active="true">
<Conditions>
<condition name="Resource" type="matchExact">resource4</condition>
<condition name="Action" type="matchExact">action4</condition>
<condition name="child" type="matchExact">child1,child2</condition>
</Conditions>
</Ruleset>
</Profile>
<Profile Desc="some description" ID="someid" Prio="0">
<Ruleset Class="classY" Desc="" ID="policyidY" Prio="10" active="true">
<Conditions>
<condition name="Resource" type="matchExact">resource99</condition>
<condition name="Action" type="matchExact">action00</condition>
<condition name="child" type="matchExact">child5</condition>
<condition name="number" type="matchExact">number1</condition>
</Conditions>
</Ruleset>
</Profile>
</Profiles>

结果我得到了这个 CSV:

"policyName"
"policyid1"



这是 powershell 输出:

PS C:\Users\Desktop> .\xmltocsv.ps1
Policy ID = policyid1
Resource = resource1
Action = action1
actor = actor1
Resource = resource4
Action = action4
child = child1,child2
Resource = resource99
Action = action00
child = child5
number = number1

这是我希望得到的 CSV 文件:

"policyName","Resource","Action","actor","child","number"
"policyid1","resource1","action1","actor1","",""
"policyidX","resource4","action4","","child1,child2",""
"policyidY","resource99","action0","","child5","number1"

最佳答案

代码的主要问题是您需要根据 <condition> 创建一个输出对象元素,具有从父元素及其子元素收集的属性值,而您正在为每个输出对象的属性创建一个单独的对象([pscustomobject]);这是一个大大简化的解决方案:

$x.Profiles.Profile.Ruleset.Conditions |
ForEach-Object {
$outputObj = [pscustomobject] @{
# Get the policy ID from the parent node.
policyId = $_.ParentNode.ID
# The following properties are filled in below.
Resource = ''
Action = ''
actor = ''
child = ''
number = ''
}
# Loop over all child elements and fill in the property
# that corresponds to the "name" attribute with the element's inner text.
# Note that the "name" *attribute* actually shadows
# the element's type-native .Name *property*.
foreach ($el in $_.ChildNodes) {
$outputObj.($el.name) = $el.InnerText
}
# Output the resulting object
$outputObj
} |
ConvertTo-Csv # To export to a *file, use Export-Csv

这会产生问题中所示的所需输出。

注意:

  • 这创建了一个 [pscustomobject]<Conditions>元素,具有从父元素收集的属性值以及一组固定的属性,如果存在于基于匹配的子元素中,则填充这些属性 name属性值,使用匹配的子元素的内部文本作为属性值。

  • 请注意属性访问 .Profiles.Profile.Ruleset.Conditions 隐式 遍历多个 <Profile><Ruleset>元素并将它们全部返回,这要归功于名为 member-access enumeration 的功能.

关于xml - 如何向 PSCustomObject 添加值(XML 到 CSV 的转换),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74394699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com