xml - 使用 Powershell 从 XML 元素中获取数据作为表格
问题描述
我尝试从 XML 元素中获取数据作为表格。下面的 XML 文件。XML 文件是导出的防火墙配置。
<?xml version="1.0" encoding="UTF-8"?>
<fpc4:Root xmlns:fpc4="http://schemas.microsoft.com/isa/config-4" xmlns:dt="urn:schemas-microsoft-com:datatypes" StorageName="FPC" StorageType="0">
<fpc4:Build dt:dt="string">7.0.9193.500</fpc4:Build>
<fpc4:Comment dt:dt="string">0</fpc4:Comment>
<fpc4:Edition dt:dt="int">32</fpc4:Edition>
<fpc4:EnterpriseLevel dt:dt="int">2</fpc4:EnterpriseLevel>
<fpc4:ExportItemClassCLSID dt:dt="string">{59740B3A-8771-492C-AF59-7764F4F939EF}</fpc4:ExportItemClassCLSID>
<fpc4:ExportItemCompatibilityVersion dt:dt="int">4</fpc4:ExportItemCompatibilityVersion>
<fpc4:ExportItemScope dt:dt="int">0</fpc4:ExportItemScope>
<fpc4:ExportItemStorageName dt:dt="string">{A86DF49D-0078-48D5-8A58-A970482FA6D6}</fpc4:ExportItemStorageName>
<fpc4:IsaXmlVersion dt:dt="string">9.0</fpc4:IsaXmlVersion>
<fpc4:OptionalData dt:dt="int">0</fpc4:OptionalData>
<fpc4:Upgrade dt:dt="boolean">0</fpc4:Upgrade>
<fpc4:ConfigurationMode dt:dt="int">0</fpc4:ConfigurationMode>
<fpc4:Arrays StorageName="Arrays" StorageType="0">
<fpc4:Array StorageName="{7149EEA4-E267-43EA-A7C8-25C3FF1EC368}" StorageType="0">
<fpc4:AdminMajorVersion dt:dt="int">0</fpc4:AdminMajorVersion>
<fpc4:AdminMinorVersion dt:dt="int">0</fpc4:AdminMinorVersion>
<fpc4:Components dt:dt="int">-1</fpc4:Components>
<fpc4:DNSName dt:dt="string"/>
<fpc4:Name dt:dt="string"/>
<fpc4:Version dt:dt="string">0</fpc4:Version>
<fpc4:Name dt:dt="string"/>
<fpc4:RuleElements StorageName="RuleElements" StorageType="0">
<fpc4:ComputerSets StorageName="ComputerSets" StorageType="0">
<fpc4:ComputerSet StorageName="{F51D0A66-40CA-4E1E-9454-A1F73834CEFC}" StorageType="2">
<fpc4:Name dt:dt="string">ScanSafe</fpc4:Name>
<fpc4:Computers StorageName="Computers" StorageType="2">
<fpc4:Computer StorageName="{9A946B36-12C6-484F-9729-97D51C53017D}" StorageType="2">
<fpc4:IPAddress dt:dt="string">100.93.231.200</fpc4:IPAddress>
<fpc4:Name dt:dt="string">1363.scans.net</fpc4:Name>
</fpc4:Computer>
</fpc4:Computers>
</fpc4:ComputerSet>
<fpc4:ComputerSet StorageName="{0598ED7C-CA3E-4461-A230-B2669B35872F}" StorageType="2">
<fpc4:Name dt:dt="string">Subscribers</fpc4:Name>
<fpc4:Computers StorageName="Computers" StorageType="2">
<fpc4:Computer StorageName="{1FF8B477-7DF2-4117-978A-044377B5958A}" StorageType="2">
<fpc4:IPAddress dt:dt="string">111.111.111.111</fpc4:IPAddress>
<fpc4:Name dt:dt="string">Client1</fpc4:Name>
</fpc4:Computer>
<fpc4:Computer StorageName="{43F2C2EB-BB08-4B2E-A05C-9D61E299820D}" StorageType="2">
<fpc4:IPAddress dt:dt="string">222.222.222.333</fpc4:IPAddress>
<fpc4:Name dt:dt="string">Client2</fpc4:Name>
</fpc4:Computer>
<fpc4:Computer StorageName="{6F1CA232-9C17-48B8-A794-65037301C24C}" StorageType="2">
<fpc4:IPAddress dt:dt="string">111.111.111.112</fpc4:IPAddress>
<fpc4:Name dt:dt="string">Client3</fpc4:Name>
</fpc4:Computer>
</fpc4:Computers>
<fpc4:AddressRanges StorageName="AddressRanges" StorageType="2">
<fpc4:AddressRange StorageName="{C7CD37CF-788B-45A0-9A44-2C0DA7C00D37}" StorageType="2">
<fpc4:IPFrom dt:dt="string">222.222.222.338</fpc4:IPFrom>
<fpc4:IPTo dt:dt="string">222.222.222.340</fpc4:IPTo>
<fpc4:Name dt:dt="string">Range 1 </fpc4:Name>
</fpc4:AddressRange>
<fpc4:AddressRange StorageName="{BC77F5FD-1CBF-4EDB-9968-2DD5ADA9090B}" StorageType="2">
<fpc4:IPFrom dt:dt="string">222.222.222.390</fpc4:IPFrom>
<fpc4:IPTo dt:dt="string">222.222.222.400</fpc4:IPTo>
<fpc4:Name dt:dt="string">Range 2</fpc4:Name>
</fpc4:AddressRange>
</fpc4:AddressRanges>
</fpc4:ComputerSet>
</fpc4:ComputerSets>
</fpc4:RuleElements>
</fpc4:Array>
</fpc4:Arrays>
</fpc4:Root>
我对以下元素中的数据感兴趣。
<fpc4:ComputerSet StorageName="{0598ED7C-CA3E-4461-A230-B2669B35872F}" StorageType="2">
到目前为止,我已经尝试过。下列的
PS H:\> $XMLfile = 'C:\tmp\asd.xml'
[XML]$xml = Get-Content $XMLfile
$xml.Root.Arrays.Array.RuleElements.ComputerSets.ComputerSet.Item(1)
以下哪个返回,我怎样才能让它显示名称/计算机元素内的数据?
StorageName : {0598ED7C-CA3E-4461-A230-B2669B35872F}
StorageType : 2
Name : Name
Computers : Computers
AddressRanges : AddressRanges
$xml.Root.Arrays.Array.RuleElements.ComputerSets.InnerText | Format-Table
将所有数据作为不可读的单个字符串返回。| 格式表不起作用。
我想在这样的表中获取数据
Name IPAddress
Client1 111.111.111.111
Client2 222.222.222.333
Name AddressRanges
Range 1 222.222.222.338
222.222.222.340
Range 2 222.222.222.390
222.222.222.400
我认为 foreach 循环/循环会有所帮助,但目前我不知道如何做到这一点。
谢谢你。
解决方案
您需要两个循环,您可以在其中构建仅具有感兴趣属性的自定义对象,这既有助于以后的编程处理,又可以输出感兴趣的表格格式:
# Read the XML file into a System.Xml.XmlDocument DOM ([xml]).
$xml = [xml] (Get-Content -Raw 'C:\tmp\asd.xml')
# Get a reference to the common parent element of the elements of interest.
$parentEl = $xml.Root.Arrays.Array.RuleElements.ComputerSets.ComputerSet[1]
# Loop over computers and create custom objects.
$computers = foreach ($computer in $parentEl.Computers.Computer) {
[pscustomobject] @{
Name = $computer.Name.InnerText
IPAddress = $computer.IPAddress.InnerText
}
}
# Loop over address ranges.
$ranges = foreach ($range in $parentEl.AddressRanges.AddressRange) {
[pscustomobject] @{
Name = $range.Name.InnerText
AddressRange = $range.IPFrom.InnerText, $range.IPTo.InnerText
}
}
# For display, print the computers and range separately.
$computers | Format-Table
$ranges | Format-Table
注意需要Format-Table
单独使用;如果您同时将两个集合发送到Format-Table
( $computer, $ranges | Format-Table
),则 仅第一个集合中对象的属性将决定表列,因此您不会看到第二个集合中对象的唯一属性;也就是说,输出$computer, $ranges
将按预期显示计算机,但会丢失AddressRange
范围的属性值。
请记住,Format-*
cmdlet 只能用于创建显示表示,不能用于进一步的编程处理;在手头的情况下,您可以将$computers
and$ranges
用于后者。
请注意,这同样适用于Out-File
/ >
:它们隐式使用cmdlet将用于显示的表示保存到文件中。在本例中,由于输入对象的属性少于 4 个,因此被隐式应用。Format-*
Format-Table
因此,如果要在单个输出文件中捕获两个用于显示的表表示,则必须再次使用单独的命令:
$computers | Out-File -FilePath $out_file # or: $computers > $out_file
$ranges | Out-File -FilePath $out_file -Append # or: $ranges >> $out_file
上述产量:
Name IPAddress
---- ---------
Client1 111.111.111.111
Client2 222.222.222.333
Client3 111.111.111.112
Name AddressRange
---- ------------
Range 1 {222.222.222.338, 222.222.222.340}
Range 2 {222.222.222.390, 222.222.222.400}
推荐阅读
- python - PYMC3混合模型:帮助理解多变量模型
- dialogflow-es - 来自数据库的 Dialogflow 插槽验证
- image-processing - 理解颜色如何应用于每个像素的问题
- xamarin - 在 Xamarin Forms 中关闭浏览器而无需用户交互
- c# - Asp.Net Core MVC Web 应用程序中的单元测试
- android - Kotlin GoogleMaps ClusterManager 返回的集群项目大小小于最初传递给它的项目大小
- csv - 使用 Overwrite 将 PySpark Dataframe 写入 GCS
- vue.js - 发布新的Vue应用程序版本时如何强制清除chrome中的缓存
- flutter - 如何转换为未知的通用运行时类型(C# ChangeType 等效项)
- python - beautifulsoup for loop 仅提取第一页数据