将.XML解析为.CSV 将节点写入列

问题描述 投票:0回答:1

我已经无计可施了。尝试将带有块的大型 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 powershell csv parsing xml-parsing
1个回答
0
投票

对于巨大的 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
© www.soinside.com 2019 - 2024. All rights reserved.