再试一次。好的,我有一个 powershell 脚本来处理目录中的 .xml 文件。对于每个 .xml 文件,脚本都会处理它,查找每个实例并提取每个节点内的所有数据。
当我尝试将结果写入 .csv 文件时,我遇到的挑战是空的。没有标题,没有数据,什么都没有。我一直在绞尽脑汁为什么它不简单地将数据写入 .csv 文件
代码
# Define the directory containing the XML files
$directory = "C:\test\"
# Get all XML files in the directory
$xmlFiles = Get-ChildItem -Path $directory -Filter *.xml
# Loop through each XML file
foreach ($file in $xmlFiles) {
# Load the XML content
[xml]$xmlContent = Get-Content -Path $file.FullName
# Initialize an array to hold the extracted data
$data = @()
# Loop through each AuditRecord node
foreach ($auditRecord in $xmlContent.SelectNodes("//AuditRecord")) {
$record = New-Object PSObject -Property @{
AuditRecordID = AuditRecordID
UserID = PIUser.UserID
UserName = PIUser.Name
UTCSeconds = PITime.UTCSeconds
LocalDate = PITime.LocalDate
PIModuleAction = PIConfigurationDB.PIModules.Action
PIModuleUniqueID = PIConfigurationDB.PIModules.PIModule.UniqueID -join ", "
PIModuleName = PIConfigurationDB.PIModules.PIModule.Name
PIModuleAttribName = PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Name -join ", "
DateTimeXSBefore = PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.Before.Type[0]
DateTimeXSAfter = PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.After.Type[0]
PIModuleAttribName2 = PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Name[1]
LongBefore = PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.Before.Type[1]
LongAfter = PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.After.Type[1]
PIModuleAttribName3 = PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.Name
PIPropertyName = PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.Action
PIPropertyAction = PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.ParentUNC_Name
hexbinBefore = PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.Value.Before.Type
hexbinAfter = PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.Value.After.Type
}
$data += $record
}
# Define the output CSV file path
$csvFilePath = Join-Path -Path $directory -ChildPath ($file.BaseName + ".csv")
# Export the data to a CSV file
$data | Export-Csv -Path $csvFilePath -NoTypeInformation
}
.XML 示例
<AuditRecord AuditRecordID="b066447a-20de-4659-8e5e-41ecb27d9d39">
<PIUser UserID="1" Name="piadmin"/>
<PITime UTCSeconds="1711662501" LocalDate="2024-03-28T17:48:21-04:00" />
<PIConfigurationDB>
<PIModules Action="Edit">
<PIModule UniqueID="feea9e80-3d3f-4f45-b58d-275e4845bcde, 31-Dec-69 16:00:01" Name="Database">
<PIModuleAttributes>
<PIModuleAttribute Name="ModifyDate">
<Value>
<Before Type="xs:dateTime">2024-03-28T17:47:42-04:00</Before>
<After Type="xs:dateTime">2024-03-28T17:48:21-04:00</After>
</Value>
</PIModuleAttribute>
<PIModuleAttribute Name="Revision">
<Value>
<Before Type="xs:long">35738</Before>
<After Type="xs:long">35739</After>
</Value>
</PIModuleAttribute>
</PIModuleAttributes>
<PIProperties>
<PIProperty Name="TemplateDataSet" Action="Edit" ParentUNC_Name="\\PIProperties">
<Value>
<Before Type="xs:hexBinary"></Before>
<After Type="xs:hexBinary"></After>
</Value>
</PIProperty>
</PIProperties>
</PIModule>
</PIModules>
</PIConfigurationDB>
</AuditRecord>
期望的输出
$Directory = 'C:\Test\'
Get-ChildItem -Path $Directory -Filter *.xml | %{
$CsvFilePath = Join-Path -Path $Directory -ChildPath ($_.BaseName + ".csv")
[xml](Get-Content -Path $_.FullName) |
Select-Xml "//AuditRecord" |
Select-Object -ExpandProperty Node | %{
[PSCustomObject]@{
AuditRecordID = $_.AuditRecordID
UserID = $_.PIUser.UserID
UserName = $_.PIUser.Name
UTCSeconds = $_.PITime.UTCSeconds
LocalDate = $_.PITime.LocalDate
PIModuleAction = $_.PIConfigurationDB.PIModules.Action
PIModuleUniqueID = $_.PIConfigurationDB.PIModules.PIModule.UniqueID -join ", "
PIModuleName = $_.PIConfigurationDB.PIModules.PIModule.Name
PIModuleAttribName = $_.PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Name -join ", "
DateTimeXSBefore = $_.PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.Before.Type[0]
DateTimeXSAfter = $_.PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.After.Type[0]
PIModuleAttribName2 = $_.PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Name[1]
LongBefore = $_.PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.Before.Type[1]
LongAfter = $_.PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.After.Type[1]
PIModuleAttribName3 = $_.PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.Name
PIPropertyName = $_.PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.Action
PIPropertyAction = $_.PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.ParentUNC_Name
hexbinBefore = $_.PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.Value.Before.Type
hexbinAfter = $_.PIConfigurationDB.PIModules.PIModule.PIProperties.PIProperty.Value.After.Type
}
} | Export-Csv -Path $CsvFilePath -NoTypeInformation
}
将会导致
"AuditRecordID","UserID","UserName","UTCSeconds","LocalDate","PIModuleAction","PIModuleUniqueID","PIModuleName","PIModuleAttribName","DateTimeXSBefore","DateTimeXSAfter","PIModuleAttribName2","LongBefore","LongAfter","PIModuleAttribName3","PIPropertyName","PIPropertyAction","hexbinBefore","hexbinAfter"
"b066447a-20de-4659-8e5e-41ecb27d9d39","1","piadmin","1711662501","2024-03-28T17:48:21-04:00","Edit","feea9e80-3d3f-4f45-b58d-275e4845bcde, 31-Dec-69 16:00:01","Database","ModifyDate, Revision","xs:dateTime","xs:dateTime","Revision","xs:long","xs:long","TemplateDataSet","Edit","\\PIProperties","xs:hexBinary","xs:hexBinary"
那么我们来谈谈吧 首先,您的一些 XML 路径略有错误 示例
$_.PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.Before.Type[0]
退货
xs:dateTime
你想要的更像是
$_.PIConfigurationDB.PIModules.PIModule.PIModuleAttributes.PIModuleAttribute.Value.Before[0].'#text'
退货
2024-03-28T17:47:42-04:00
似乎有一些类似的情况,只需要稍微调整一下路径。
那么为什么你的脚本不起作用?
让我们看一下代码示例
foreach ($auditRecord in $xmlContent.SelectNodes("//AuditRecord")) {
$record = New-Object PSObject -Property @{
AuditRecordID = AuditRecordID
UserID = PIUser.UserID
}
}
我希望你的代码会出现上面的错误
您正在使用 var $auditRecord 循环 XML //AuditRecord
但是当您进入循环时,在设置 PSObject 属性的值时不会调用 $auditRecord。
我希望看到的更像是
foreach ($auditRecord in $xmlContent.SelectNodes("//AuditRecord")) {
$record = New-Object PSObject -Property @{
AuditRecordID = $auditRecord.AuditRecordID
UserID = $auditRecord.PIUser.UserID
}
}