PowerShell XML 导出到 CSV - 无法获得一些子值
Posted
技术标签:
【中文标题】PowerShell XML 导出到 CSV - 无法获得一些子值【英文标题】:PowerShell XML export to CSV - can't get some child value 【发布时间】:2020-01-15 15:35:27 【问题描述】:我有这个 XML 样式文件。
<?xml version="1.0" encoding="UTF-8" ?>
<searchresults timestamp='ttt' www='www' qqq='qqq' url='url'>
<obj id='00001' type='Random' name1='Mow' class='Data' >
<tags>
<tag key="Car" value="4x4" />
<tag key="City" value="Big" />
<tag key="Dog" value="Loud" />
</tags>
<details>
<name desc="fulldesc">Full description</name>
</details>
<i1>Empty</i1>
<i2>False</i2>
<i3>True</i3>
</obj>
<obj id='00002' type='Random' name1='AGP' class='BigData' >
<tags>
<tag key="Car" value="Broken" />
<tag key="City" value="Fresh" />
<tag key="Dog" value="Long" />
</tags>
<details>
<name desc="fulldesc">Good desc</name>
</details>
<i1>True</i1>
<i2></i2>
<i3>False</i3>
</obj>
</searchresults>
我需要将所有内容导出到 CSV。特别是我需要来自标签和详细信息容器的数据。在这个子节点中,信息有这样的方案——键和值。我需要make(键必须是-列名)(值必须是-键列值)。 (fulldesc = 列名,“完整描述” - fulldesc 列的内容) 像这样
id type name class Car City Dog fulldesc i1 i2 i3 -- ---- ---- ----- ---- ---- ---- -------- -- -- -- id1 type1 name1 class1 4x4 Big Loud 完整描述 Information1 Information2 Information3 id2 type2 name2 class2 4x4 Big Loud 完整描述 Information1 Information2 Information3我使用此代码进行导出 - 它工作得很好,但我无法从 XML 中获取一些内容。
[xml]$inputFile = Get-Content ".\xmlFile.xml"
$inputFile.searchresults.ChildNodes |
Export-Csv ".\xmlFile.csv" -NoTypeInformation -Delimiter:";" -Encoding:UTF8
Import-Csv -Delimiter ';' -Encoding:UTF8 -Path ".\xmlFile.csv" | Format-Table
结果:
id type name class tags details i1 i2 i3 -- ---- ---- ----- ---- -------- -- -- -- id1 type1 name1 class1 System.Xml.XmlElement System.Xml.XmlElement Information1 Information2 Information3 id2 type2 name2 class2 System.Xml.XmlElement System.Xml.XmlElement Information1 Information2 Information3在标签和详细信息列中没有内容。
当我使用这段代码时:
[xml]$xml = Get-Content .\XML\12.xml
$xml.SelectNodes("//*")
我从 XML 接收所有信息:
时间戳:ttt 万维网:万维网 QQ : QQ 网址:网址 对象:对象,对象 编号:00001 类型:随机 名称1:割草 类:数据 标签:标签 细节:细节 i1 : 空的 i2:错误 i3 : 真 标签:标签,标签,标签 关键:汽车 价值:4x4 关键:城市 价值:大 关键:狗 价值:响亮 名称:名称 描述:全描述 #text : 完整描述 #text : 空 #文本:错误 #文本:真 编号:00002 类型:随机 名称1:AGP 类:大数据 标签:标签 细节:细节 i1:真 我2: i3:错误 标签:标签,标签,标签 关键:汽车 价值:破碎 关键:城市 价值:新鲜 关键:狗 值:长 名称:名称 描述:全描述 #text : 很好的描述 #文本:真 名称:i2 本地名称:i2 命名空间URI: 字首 : 节点类型:元素 父节点:对象 所有者文档:#document IsEmpty : 假 属性 : 有属性:假 架构信息:System.Xml.XmlName 内部Xml: 内文: 下一个兄弟姐妹:i3 上一个兄弟姐妹:i1 价值 : 子节点: 第一个孩子 : 最后一个孩子 : HasChildNodes:假 IsReadOnly : 假 外部Xml:【问题讨论】:
相关:Convert XML to CSV automatically in Powershell 或 similar one 节点<tags>
和<details>
包含结构化信息。您需要在代码中定义您希望如何将其转换为字符串。您可以使用calculated properties 来实现。
【参考方案1】:
如果您愿意硬编码 CSV 列名和列数,您可以使用calculated properties,正如Ansgar Wiechers 建议的那样:
# Read the input file into an XML DOM.
[xml] $xml = Get-Content -Raw ".\xmlFile.xml"
# Loop over all <obj> children of <searchresults>
$xml.searchresults.obj | Select-Object id, type, name1, class,
@ n='Car'; e = $_.tags.tag[0].value ,
@ n='City'; e = $_.tags.tag[1].value ,
@ n='Dog'; e = $_.tags.tag[2].value ,
@ n='desc'; e = $_.details.name.'#text' ,
i1, i2, i3 |
Export-Csv ".\xmlFile.csv" -NoTypeInformation -Delimiter ";" -Encoding:UTF8
如果列名必须从 XML 文档属性和元素名动态派生,和/或 列数是变量 :
注意:
对于给定的输入 XML 文档,您需要确保至少 first 输出对象具有您想要 CSV 的 所有 属性(列)要包含的文件。它是第一个锁定输出列的对象。
为了不对列的名称和数量做出预先假设,下面的解决方案添加了在 XML 文档中找到的属性,这意味着输出 CSV 列排序,这意味着:
您必须依赖包含相同属性集/子元素集的所有 <obj>
元素变成列,或者使用 maximum 集预填充 $properties
哈希表输出列数,如果已知。
否则,如果要更改输出列的顺序,则需要额外的逻辑。
# Read the input file into an XML DOM.
[xml] $xml = Get-Content -Raw ".\xmlFile.xml"
# Loop over all <obj> children of <searchresults>
$xml.searchresults.obj | ForEach-Object
$el = $_ # The input element at hand.
# Initialize an ordered hashtable in which to collect / construct the properties
# to send to the CSV file.
$properties = [ordered] @
# Loop over all attributes / children of the given <obj>
foreach ($propName in ($el | Get-Member -Type Property).Name)
switch ($propName)
'tags'
# Instead of a single 'tags' property, create individual properties
# based on the keys and values of the <tag> elements.
foreach ($child in $el.tags.tag)
$properties.($child.Key) = $child.Value
break
'details'
# Instead of a 'details' property, use the <name> element's
# 'desc' attribute value as the property name and assign it
# the element's content.
$properties.($el.$_.name.desc) = $el.$_.name.'#text'
break
default
# All other properties: pass them through.
$properties.$propName = $el.$propName
# Output the ordered hashtable as a custom object, whose property names will become
# the CSV column headers and whose values will become the row values.
[pscustomobject] $properties
| Export-Csv ".\xmlFile.csv" -NoTypeInformation -Delimiter ";" -Encoding:UTF8
该方法的核心是$el | Get-Member -Type Property).Name
,它从每个<obj>
元素中提取所有属性名称,因为这些属性代表给定元素的属性和子元素。
这允许使用switch
语句对属性进行循环、传递或预处理。
【讨论】:
很高兴听到它有帮助,@DenisOr;我的荣幸。以上是关于PowerShell XML 导出到 CSV - 无法获得一些子值的主要内容,如果未能解决你的问题,请参考以下文章
PowerShell:ConvertFrom-Json 将多个对象导出到 csv
Powershell:将所有具有“NetworkRuleSet”属性的 Azure 存储帐户列出/导出到 CSV