我已经无计可施了。尝试将带有块的大型 xml 文件解析为 .csv 文件。找到的每个子节点都应该有自己的列。不太清楚为什么我无法将内部文本写入 .csv 文件。
问题:代码似乎没有将任何对象写入 .csv。我所看到的只是标题,但没有数据,尽管输入文件中有超过 100 个块。
代码
# Define the directory containing the XML files
$directory = "c:\batch1\test"
# Get all XML files in the directory
$xmlFiles = Get-ChildItem -Path $directory -Filter *.xml
foreach ($xmlFile in $xmlFiles) {
# Load the XML content
[xml]$xmlContent = Get-Content -Path $xmlFile.FullName
# Extract all AuditRecord nodes
$auditRecords = $xmlContent.SelectNodes("//AuditRecord")
# Create a list to store the data
$data = @()
foreach ($record in $auditRecords) {
# Create a hashtable to store the record data
$recordData = @{}
foreach ($node in $record.ChildNodes) {
$recordData[$node.Name] = $node.InnerText
}
$data += [pscustomobject]$recordData
}
# Define the output CSV file name
$csvFileName = [System.IO.Path]::ChangeExtension($xmlFile.FullName, "csv")
# Export the data to a CSV file
$data | Export-Csv -Path $csvFileName -NoTypeInformation
}
大型 .xml 文件中的示例 XML 块
<AuditRecord AuditRecordID="ca7a433e-b45f-4ed1-8169-5fc70547b35e">
<PIUser UserID="1" Name="theadmin"/>
<PITime UTCSeconds="1708987340" LocalDate="2024-02-26T17:42:20-05:00"/>
<PIConfigurationDB>
<PIModules Action="Edit">
<PIModule UniqueID="7c03e74e-ad46-4ada-8234-50c7cd2699f0, 31-Dec-69 16:00:01" Name="MDB-AFMigrationData">
<PIModuleAttributes>
<PIModuleAttribute Name="ModifyDate">
<Value>
<Before Type="xs:dateTime">2024-02-26T17:42:05-05:00</Before>
<After Type="xs:dateTime">2024-02-26T17:42:20-05:00</After>
</Value>
</PIModuleAttribute>
<PIModuleAttribute Name="Revision">
<Value>
<Before Type="xs:long">222325</Before>
<After Type="xs:long">222326</After>
</Value>
</PIModuleAttribute>
</PIModuleAttributes>
<PIProperties>
<PIProperty Name="AFCST" Action="Edit" ParentUNC_Name="\\PIProperties">
<Value>
<Before Type="xs:double">1708987319.220131</Before>
<After Type="xs:double">1708987325.796927</After>
</Value>
</PIProperty>
</PIProperties>
</PIModule>
</PIModules>
</PIConfigurationDB>
</AuditRecord>
所需输出(示例)
userid name utcseconds localdate action
----- ---- ---------- --------- ------
1 theadmin 1722272177 2024-07-29T12:56:17-04:00 edit... .etc.. etc.. etc
对于巨大的 xml 文件,您需要使用 XmlReader。 下面是使用 Xml Linq 和 XmlReader 的代码。
using assembly System.Xml
using assembly System.Xml.Linq
$xmlFilename = 'c:\temp\test.xml'
$csvFilename = 'c:\temp\test.csv'
$table = [System.Collections.Generic.List[pscustomobject]]::new()
$reader = [System.Xml.XmlReader]::Create($xmlFilename)
While(-not $reader.EOF)
{
if($reader.Name -ne 'AuditRecord')
{
$reader.ReadToFollowing('AuditRecord') | out-null;
}
if(-not $reader.EOF)
{
$auditRecord = [System.Xml.Linq.XElement][System.Xml.Linq.XElement]::ReadFrom($reader);
$PIUser = $auditRecord.Element('PIUser')
$UserID = $PIUser.Attribute('UserID').Value
$Name = $PIUser.Attribute('Name').Value
$PITime = $auditRecord.Element('PITime')
$UTCSeconds = $PITime.Attribute('UTCSeconds').Value
$LocalDate = $PITime.Attribute('LocalDate').Value
$PIModules = $auditRecord.Descendants('PIModules')[0]
$Action = $PIModules.Attribute('Action').Value
foreach($PIModule in $auditRecord.Descendants('PIModule'))
{
$UniqueID = $PIModule.Attribute('UniqueID').Value
$PIModuleName = $PIModule.Attribute('Name').Value
foreach($PIModuleAttribute in $PIModule.Descendants('PIModuleAttribute'))
{
$Before = $PIModuleAttribute.Descendants('Before')[0].Value
$After = $PIModuleAttribute.Descendants('After')[0].Value
$newRow = [pscustomobject]@{
UserID = $UserID
Name = $Name
UTCSeconds = $UTCSeconds
LocalDate = $LocalDate
Action= $Action
UniqueID = $UniqueID
'PIModule Name' = $PIModuleName
Before = $Before
After = $After
}
$table.Add($newRow) | out-null
}
}
}
}
$table | Export-Csv -Path $csvFilename -NoTypeInformation