从XML生成表格:提取属性为表头、InnerXml为值
从XML文件中提取指定字段生成结构化表格(PowerShell实现)
问题描述
我有大量包含目标数据的XML文件,需要提取指定属性作为表头,对应节点的InnerXml作为表格值。已能处理多文档循环,但在提取单个属性和InnerXml并转换为表头-值对应结构时遇到困难,同时希望能根据属性名称筛选需要的列。
XML示例
<?xml version="1.0" encoding="UTF-8"?> <files> <file type="lcmContract" id="72187_fi20190000046444"> <title>Bacon Cheeseburger</title> <field name="lcmHeaderGrp"></field> <field name="lcmHasNote">_image=custom/crmNote.gif</field> <field name="lcmSubject">Bacon Cheeseburgers are Good</field> <field name="lcmPrincipal">Frontline Rock</field> <field name="lcmClosingDate">@20190704</field> <field name="lcmAclList"> Royalties LEGAL_DEPT LegalExt MktgRock AllExceptRestricted LegalTemp LEGAL_DEPT_READ lcmAdmin CONTRACT-Administrator </field> </file> </files>
期望输出表格
| title | lcmSubject | lcmPrincipal | lcmClosingDate | lcmAclList |
|---|---|---|---|---|
| Bacon Cheeseburger | Bacon Cheeseburgers are Good | Frontline Rock | @20190704 | Royalties,LEGAL_DEPT,LegalExt,MktgRock,AllExceptRestricted,LegalTemp,LEGAL_DEPT_READ,lcmAdmin,CONTRACT-Administrator |
已尝试的脚本片段
[xml]$xmlFile = Get-Content -Path C:\Doc.xml # 返回列表形式的表头 $xmlFile.files.file.ChildNodes | Select-Object -Expand Name # 返回列表形式的对应值 $xmlFile.files.file.ChildNodes | Select-Object -Expand InnerXml
解决方案
1. 单个XML文件处理脚本
核心思路是将每个节点的名称/属性名与值映射为自定义对象,再筛选目标字段,同时处理lcmAclList的换行转逗号格式:
# 加载XML文件 [xml]$xmlFile = Get-Content -Path "C:\Doc.xml" # 定义需要保留的字段列表(按需调整) $targetFields = @("title", "lcmSubject", "lcmPrincipal", "lcmClosingDate", "lcmAclList") # 初始化自定义对象存储结果 $outputObj = [PSCustomObject]@{} # 遍历所有子节点 foreach ($node in $xmlFile.files.file.ChildNodes) { # 处理普通节点(如<title>) if ($node.Name -ne "field") { $fieldName = $node.Name $fieldValue = $node.InnerXml.Trim() } # 处理带name属性的<field>节点 else { $fieldName = $node.GetAttribute("name") $fieldValue = $node.InnerXml.Trim() # 特殊处理lcmAclList:换行转逗号分隔 if ($fieldName -eq "lcmAclList") { $fieldValue = $fieldValue -split "`r?`n" | Where-Object { $_ -ne "" } | Join-String -Separator "," } } # 仅添加目标字段到结果对象 if ($targetFields -contains $fieldName) { $outputObj | Add-Member -MemberType NoteProperty -Name $fieldName -Value $fieldValue } } # 输出结构化表格 $outputObj | Format-Table -AutoSize
2. 多XML文件批量处理
如果要处理文件夹下所有XML文件,套入循环即可:
# 目标XML文件夹路径 $xmlFolder = "C:\YourXmlFolder" # 需要保留的字段列表 $targetFields = @("title", "lcmSubject", "lcmPrincipal", "lcmClosingDate", "lcmAclList") # 存储所有结果的数组 $allResults = @() # 遍历所有XML文件 Get-ChildItem -Path $xmlFolder -Filter "*.xml" | ForEach-Object { [xml]$xmlFile = Get-Content -Path $_.FullName $outputObj = [PSCustomObject]@{} foreach ($node in $xmlFile.files.file.ChildNodes) { if ($node.Name -ne "field") { $fieldName = $node.Name $fieldValue = $node.InnerXml.Trim() } else { $fieldName = $node.GetAttribute("name") $fieldValue = $node.InnerXml.Trim() if ($fieldName -eq "lcmAclList") { $fieldValue = $fieldValue -split "`r?`n" | Where-Object { $_ -ne "" } | Join-String -Separator "," } } if ($targetFields -contains $fieldName) { $outputObj | Add-Member -MemberType NoteProperty -Name $fieldName -Value $fieldValue } } $allResults += $outputObj } # 输出所有结果的表格 $allResults | Format-Table -AutoSize # 可选:导出结果到CSV文件 $allResults | Export-Csv -Path "C:\Output\ContractData.csv" -NoTypeInformation -Encoding UTF8
关键说明
- 字段筛选:通过
$targetFields数组指定需要保留的字段,不需要的字段自动跳过 - 节点区分:区分普通节点(如
<title>)和带name属性的<field>节点,分别提取字段名 - 特殊值处理:针对
lcmAclList的多行内容,按换行分割后过滤空行,再用逗号拼接为字符串 - 结构化输出:用
PSCustomObject构建键值对,确保表头与值一一对应,直接通过Format-Table生成符合预期的表格
内容的提问来源于stack exchange,提问作者baconfeltoon
相关产品推荐
相关产品推荐

