Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用powershell将重复的xml节点转换为逗号分隔的字符串_Xml_Powershell_Nodes - Fatal编程技术网

如何使用powershell将重复的xml节点转换为逗号分隔的字符串

如何使用powershell将重复的xml节点转换为逗号分隔的字符串,xml,powershell,nodes,Xml,Powershell,Nodes,我有大约13000个以XML格式格式化的日志文件,我需要将它们全部转换为电子表格\csv文件 正如您将看到的,我不是程序员,但我已经尝试过了。 我已经编写了一个powershell脚本来获取第一个节点并创建一个逗号分隔的字符串,但是我一直在获取最后一个节点,它可以包含从没有条目到几十个条目的任何内容 xml文件的示例: <?xml version="1.0" encoding="utf-8"?> <MigrationUserStatus> <User>us

我有大约13000个以XML格式格式化的日志文件,我需要将它们全部转换为电子表格\csv文件

正如您将看到的,我不是程序员,但我已经尝试过了。
我已经编写了一个powershell脚本来获取第一个节点并创建一个逗号分隔的字符串,但是我一直在获取最后一个节点,它可以包含从没有条目到几十个条目的任何内容

xml文件的示例:

<?xml version="1.0" encoding="utf-8"?>
<MigrationUserStatus>
  <User>username@domain.com</User>
  <StoreList>
    <EmailMigrationStatus>
      <MigrationStatus value="Success" />
      <FolderList>
        <TotalCount value="6" />
        <SuccessCount value="3" />
        <FailCount value="3" />
        <FailedMessages>
          <ErrorMessage>GDSTATUS_BAD_REQUEST:Permanent failure: BadAttachment</ErrorMessage>
          <SentTime>1601-01-01T00:00:00.000Z</SentTime>
          <ReceiveTime>1601-01-01T00:00:00.000Z</ReceiveTime>
        </FailedMessages>
        <FailedMessages>
          <ErrorMessage>GDSTATUS_BAD_REQUEST:Permanent failure: BadAttachment</ErrorMessage>
          <SentTime>1601-01-01T00:00:00.000Z</SentTime>
          <ReceiveTime>1601-01-01T00:00:00.000Z</ReceiveTime>
        </FailedMessages>
        <FailedMessages>
          <MessageSubject>Hey</MessageSubject>
          <ErrorMessage>GDSTATUS_BAD_REQUEST:Permanent failure: BadAttachment</ErrorMessage>
          <SentTime>2013-01-07T02:51:17.000Z</SentTime>
          <ReceiveTime>2013-01-07T02:51:17.000Z</ReceiveTime>
          <MessageSize value="2881" />
        </FailedMessages>
        <StartTime>2013-01-07T01:52:46.000Z</StartTime>
        <EndTime>2013-01-07T04:41:59.000Z</EndTime>
      </FolderList>
      <StartTime>2013-01-07T01:52:43.000Z</StartTime>
      <EndTime>2013-01-07T04:41:59.000Z</EndTime>
    </EmailMigrationStatus>
    <StartTime>2013-01-07T01:52:43.000Z</StartTime>
    <EndTime>2013-01-07T04:41:59.000Z</EndTime>
  </StoreList>
</MigrationUserStatus>
下一步就是我要摆脱困境的地方。我想读取每个FailedMessages节点,并将其构建为另一个逗号分隔的字符串

foreach ($FMessage in $Status.MigrationUserStatus.StoreList.EmailMigrationStatus.FolderList.FailedMessages) {
$csvpt2 +=$FMessage + ","
}
期望输出:

GDSTATUS_BAD_REQUEST:Permanent failu... 1601-01-01T00:00:00.000Z                1601-01-01T00:00:00.000Z,GDSTATUS_BAD_REQUEST:Permanent failu... 1601-01-01T00:00:00.000Z                1601-01-01T00:00:00.000Z,.......
我要么在$FMessage中得到空白,要么方法调用失败,因为结尾有+“,”,所以我需要修复这个问题

然后我将连接成最后一个字符串并写入文件

$csv +=$csvpt1 + "," + $csvpt2
$outfile.WriteLine($csv)
}
$outfile.Close()
在添加的愿望列表中,能够为n个列创建csv文件列标题故障也将非常好,如FailedMessages节点的最大数量所示


非常感谢您的帮助。

Powershell具有对XML的本机支持,也许这将帮助您开始

它还有一个本机CSV导出器,带有导出CSV:)

对于其他字段,您可以检查它们是否存在,如果它们很容易添加,则可以添加它们,这应能起作用:

foreach ($Failure in $Failures)
{
    if ($Failure.ErrorMessage) { $ConcatFailures += $Failure.ErrorMessage }
    if ($Failure.SentTime) { $ConcatFailures += $Failure.ErrorMessage }
    if ($Failure.ReceivedTime) { $ConcatFailures += $Failure.ReceivedTime }
    if ($Failure.MessageSubject) { $ConcatFailures += $Failure.MessageSubject }
    if ($Failure.MessageSize) { $ConcatFailures += $Failure.MessageSize }
}
要处理xml文件,您需要添加一个外部循环来遍历所有xml文件,然后将数据附加到一个在运行过程中构建的数组中。这应该满足您的需要,并对使用的路径进行一些调整:

$XMLFiles = gci "C:\Temp\" -Filter "*.xml"
$MasterArray = @()

foreach ($XMLFile in $XMLFiles)
{
    [xml]$XMLfile = gc $XMLFile.FullName

    $TempArray = @()
    $TempArray = "" | Select User, Result, TotalEmails, SuccessfulEmails, FailedEmails, Failures

    $TempArray.User = $XMLfile.MigrationUserStatus.user
    $TempArray.Result = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.MigrationStatus.value
    $TempArray.TotalEmails = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.FolderList.TotalCount.value
    $TempArray.SuccessfulEmails = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.FolderList.SuccessCount.value
    $TempArray.FailedEmails = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.FolderList.FailCount.value

    $Failures = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.FolderList.FailedMessages
    $ConcatFailures = @()

    foreach ($Failure in $Failures)
    {
        if ($Failure.ErrorMessage) { $ConcatFailures += $Failure.ErrorMessage }
        if ($Failure.SentTime) { $ConcatFailures += $Failure.ErrorMessage }
        if ($Failure.ReceivedTime) { $ConcatFailures += $Failure.ReceivedTime }
        if ($Failure.MessageSubject) { $ConcatFailures += $Failure.MessageSubject }
        if ($Failure.MessageSize) { $ConcatFailures += $Failure.MessageSize }
    }
    $TempArray.Failures = $ConcatFailures -Join "|"

    $MasterArray += $TempArray
}

$MasterArray
$MasterArray | Export-Csv -NoType "C:\Temp\export.csv"

Powershell具有对XML的本机支持,这可能有助于您入门

它还有一个本机CSV导出器,带有导出CSV:)

对于其他字段,您可以检查它们是否存在,如果它们很容易添加,则可以添加它们,这应能起作用:

foreach ($Failure in $Failures)
{
    if ($Failure.ErrorMessage) { $ConcatFailures += $Failure.ErrorMessage }
    if ($Failure.SentTime) { $ConcatFailures += $Failure.ErrorMessage }
    if ($Failure.ReceivedTime) { $ConcatFailures += $Failure.ReceivedTime }
    if ($Failure.MessageSubject) { $ConcatFailures += $Failure.MessageSubject }
    if ($Failure.MessageSize) { $ConcatFailures += $Failure.MessageSize }
}
要处理xml文件,您需要添加一个外部循环来遍历所有xml文件,然后将数据附加到一个在运行过程中构建的数组中。这应该满足您的需要,并对使用的路径进行一些调整:

$XMLFiles = gci "C:\Temp\" -Filter "*.xml"
$MasterArray = @()

foreach ($XMLFile in $XMLFiles)
{
    [xml]$XMLfile = gc $XMLFile.FullName

    $TempArray = @()
    $TempArray = "" | Select User, Result, TotalEmails, SuccessfulEmails, FailedEmails, Failures

    $TempArray.User = $XMLfile.MigrationUserStatus.user
    $TempArray.Result = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.MigrationStatus.value
    $TempArray.TotalEmails = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.FolderList.TotalCount.value
    $TempArray.SuccessfulEmails = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.FolderList.SuccessCount.value
    $TempArray.FailedEmails = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.FolderList.FailCount.value

    $Failures = $XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.FolderList.FailedMessages
    $ConcatFailures = @()

    foreach ($Failure in $Failures)
    {
        if ($Failure.ErrorMessage) { $ConcatFailures += $Failure.ErrorMessage }
        if ($Failure.SentTime) { $ConcatFailures += $Failure.ErrorMessage }
        if ($Failure.ReceivedTime) { $ConcatFailures += $Failure.ReceivedTime }
        if ($Failure.MessageSubject) { $ConcatFailures += $Failure.MessageSubject }
        if ($Failure.MessageSize) { $ConcatFailures += $Failure.MessageSize }
    }
    $TempArray.Failures = $ConcatFailures -Join "|"

    $MasterArray += $TempArray
}

$MasterArray
$MasterArray | Export-Csv -NoType "C:\Temp\export.csv"

感谢HungryHippos,我看到您的解决方案的唯一问题是,它假设只有ErrorMessage、SentTime和ReceivedTime,而在示例XML中,第三条failedmessage中有MessageSubject和MessageSize。我想包括主题,如果它存在,但它并不总是存在。再次感谢您的回复,我将看看是否可以稍微修改它,以包含MessageSubject(如果存在的话),并对您可能如何处理它稍感遗憾。也可能是(虽然我没有测试过)如果你在中添加了其他字段,那么$Null可能根本不会处理它们,除非它们存在。再次感谢HungryHippos,我尝试了另一种方式,但更喜欢并将使用你的解决方案。指定的最后一件事是,我需要对大约13000个日志文件运行它,并将它们合并到一个csv文件中。我尝试过,但它总是覆盖以前创建的csv文件。我更新了原始文件,以展示如何添加外部循环以使其正常工作:)再次感谢@HungryHippos,我稍微修改了您的代码以解决一些意外输出,因为唯一的Concatfailures是最后一个文件,这通过添加foreach解决($XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.Folderlist中的$Folderlist)我添加了一个检查,因为并非所有文件都有错误消息,最后我包括了所有计数的总和(成功、失败和总数)对于所有的文件。再次感谢,您为我省去了很多麻烦。感谢HungryHippos,我能看到您的解决方案的唯一问题是,它假设只有ErrorMessage、SentTime和ReceivedTime,而在提供的示例XML中,第三条failedmessage中有MessageSubject和MessageSize。我想包括Subject如果它存在,但它并不总是存在。再次感谢您的回复,我会看看是否可以稍微修改它,以包含MessageSubject(如果存在)。请稍微说明您如何处理它。它也可能存在(尽管我尚未测试)如果您在中添加了其他字段,$Null可能根本无法处理它们,除非它们存在。再次感谢HungryHippos,我尝试了另一种方式,但更喜欢并将使用您的解决方案。最后指定的是,我需要对大约13000个日志文件运行此操作,并将它们合并到一个csv文件中。我尝试了但它总是覆盖以前创建的csv文件。我更新了原始文件,以展示如何添加外部循环以使其工作:)再次感谢@HungryHippos,我稍微修改了您的代码以解决一些意外输出,因为唯一的Concatfailures是最后一个文件,这是通过添加foreach解决的($XMLfile.MigrationUserStatus.StoreList.EmailMigrationStatus.Folderlist中的$Folderlist)我添加了一个检查,因为不是所有文件都有错误消息,最后我包括了所有文件的所有计数总和(成功、失败和总数)。再次感谢,您为我省去了很多麻烦。