实施将PowerShell XML转换为CSV解决方案的问题

时间:2018-10-31 16:27:00

标签: xml powershell csv

我找到了一种使用PowerShell将XML转换为CSV的解决方案,我认为它可以满足我的需求in this question

解决方案示例代码如下:

$xml = [xml](Get-Content .\test.xml)

$xml.root.item | Select-Object @(
@{l="short_version";e={$_.short_version."#text"}},
@{l="long_name";e={$_.long_name."#text"}},
@{l="api_name";e={$_.api_name."#text"}},
@{l="long_version";e={$_.long_version."#text"}},
@{l="latest_stable_version";e={$_.latest_stable_version."#text"}},
@{l="automation_backend";e={$_.automation_backend."#text"}},
@{l="os";e={$_.os."#text"}}) |
Export-Csv test.csv -NoTypeInformation

但是,在对源XML进行适当的替换之后,我只生成了带有一行标题的CSV,后面是一行逗号,没有值。

我的源XML如下:

<Report>
    <Columns>
        <Col_Name>TimeStamp</Col_Name>
        <Col_Name>MessageText</Col_Name>
        <Col_Name>EventNotificationId</Col_Name>
        <Col_Name>OperatorText</Col_Name>
        <Col_Name>TimeOfAck</Col_Name>
        <Col_Name>InitDeviceId</Col_Name>
    </Columns>
    <Record>
        <TimeStamp><![CDATA[10/1/2018 1:34:06.99 PM]]></TimeStamp>
        <MessageText><![CDATA[OnLine]]></MessageText>
        <EventNotificationId><![CDATA[Path\Text]]></EventNotificationId>
        <OperatorText><![CDATA[]]></OperatorText>
        <TimeOfAck><![CDATA[1/1/1989]]></TimeOfAck>
        <InitDeviceId><![CDATA[Path\Text]]></InitDeviceId>
    </Record>
    <Record>
        ~
    </Record>

(出于谨慎考虑,我在几个地方都替换了Path \ Text。)

我的替换代码如下:

$xml = [xml](Get-Content C:\Test\test.xml)

$xml.Report.Record | Select-Object @(
@{l="TimeStamp";e={$_.TimeStamp."#text"}},
@{l="MessageText";e={$_.MessageText."#text"}},
@{l="EventNotificationId";e={$_.EventNotificationId."#text"}},
@{l="OperatorText";e={$_.OperatorText."#text"}},
@{l="TimeOfAck";e={$_.TimeOfAck."#text"}},
@{l="InitDeviceId";e={$_.InitDeviceId."#text"}}) |
Export-Csv C:\Test\test.csv -NoTypeInformation -Force

要使该解决方案对我有用,我需要更改什么?

我现在最后想到的是专有数据类型CDATA使用我当前的代码可能无法读取。如果那负责,我不确定如何从中解析纯文本字符串。同样是FWIW,我可以选择将源数据作为HTML文档获取,但是从我的快速研究中,似乎很容易将源XML文件中的CSV转换脚本编写为脚本。

谢谢。

1 个答案:

答案 0 :(得分:1)

xml解析器会将您的CDATA部分放在名为#cdata-section而不是#text的成员中。因此,您的解决方法很简单:

$xml.Report.Record | Select-Object @(
    @{l="TimeStamp";e={$_.TimeStamp."#cdata-section"}},
    @{l="MessageText";e={$_.MessageText."#cdata-section"}},
    @{l="EventNotificationId";e={$_.EventNotificationId."#cdata-section"}},
    @{l="OperatorText";e={$_.OperatorText."#cdata-section"}},
    @{l="TimeOfAck";e={$_.TimeOfAck."#cdata-section"}},
    @{l="InitDeviceId";e={$_.InitDeviceId."#cdata-section"}}) |
Export-Csv C:\Test\test.csv -NoTypeInformation -Force