根据xml节点值将数据设置为true或false

时间:2013-04-02 15:18:12

标签: xml parsing powershell sql-server-2008-r2

我的数据与本问题最底部的xml类似。这是成千上万的任务。有些节点有<DayOfWeek>个节点,有些节点没有节点。我正在努力获取这些数据并将其放入csv,以便可以将其导入到sql中。

我的目标是让每一天成为表格中的一列,每一行代表一项任务。如果计划在某一天运行,则1将在相应的日期,否则它将为0.对于此问题底部的以下数据,该表将如下所示

| taskID | mon | tue | wed | thur | fri | sat | sun |
|________|_____|_____|_____|______|_____|_____|_____|
|    1   |  1  |  0  |  0  |  1   |  1  |  1  |  0  |
|    2   |  1  |  0  |  0  |  0   |  1  |  0  |  0  |
|    3   |  1  |  1  |  1  |  1   |  1  |  1  |  1  |

我当前的ps脚本使这些数据更加垂直而不是水平。摘自代码

foreach($task in $config.Settings.Tasks.Task){
    $taskID = $task.ID
    foreach($DoW in $task.Schedules.Schedule.Days.DayOfWeek){
        $newCSV += @(New-Object -TypeName psobject -Property @{'taskID' = $taskID; 'Day' = $DoW})
    }
}
$newCSV | Export-Csv -Path c:\users\mhopkins\desktop\micSchedule\DoW.csv -notype

你能帮我们把这些数据在桌子上的工作做得更好吗?

XML snippit

<Task ID="1" Name="name1" Active="1" NextEID="11">
    <Schedules>
        <Schedule OnlyUntilFirstSuccess="0" FailIfNoSuccessInSched="0" RunEvenIfNotif="0">
            <Days>
                <DayOfWeek>Monday</DayOfWeek>
                <DayOfWeek>Friday</DayOfWeek>
                <DayOfWeek>Thursday</DayOfWeek>
                <DayOfWeek>Saturday</DayOfWeek>
            </Days>
        </Schedule>
    </Schedules>
</Task>
<Task ID="2" Name="name2" Active="1" NextEID="12">
    <Schedules>
        <Schedule OnlyUntilFirstSuccess="0" FailIfNoSuccessInSched="0" RunEvenIfNotif="0">
            <Days>
                <DayOfWeek>Monday</DayOfWeek>
                <DayOfWeek>Friday</DayOfWeek>
            </Days>
        </Schedule>
    </Schedules>
</Task>
<Task ID="3" Name="name3" Active="0" NextEID="24" TT="COS" AR="0">
    <Schedules>
        <Schedule OnlyUntilFirstSuccess="0" FailIfNoSuccessInSched="0" RunEvenIfNotif="1">
            <Days>
                <DayOfWeek>Monday</DayOfWeek>
                <DayOfWeek>Tuesday</DayOfWeek>
                <DayOfWeek>Wednesday</DayOfWeek>
                <DayOfWeek>Thursday</DayOfWeek>
                <DayOfWeek>Friday</DayOfWeek>
                <DayOfWeek>Saturday</DayOfWeek>
                <DayOfWeek>Sunday</DayOfWeek>
            </Days>
        </Schedule>
    </Schedules>
</Task>

2 个答案:

答案 0 :(得分:1)

我必须在XML片段中添加行以使其适用于PowerShell。

<xml>
...
</xml>

我正在使用PowerShell v 3.0并将其运行起来。

$config = [xml](get-content 'dat.xml')

foreach($task in $config.xml.Task){

    $props = @{
        'taskID'=$task.ID
        'Sunday'=$NULL
        'Monday'=$NULL
        'Tuesday'=$NULL
        'Wednesday'=$NULL
        'Thursday'=$NULL
        'Friday'=$NULL
        'Saturday'=$NULL
    }

    foreach($DoW in $task.Schedules.Schedule.Days.DayOfWeek){
        foreach($day in $DoW){
            #POWERSHELL!!!
            $props.$day = $true #Or equals 1 whatever  
        }   
    }

    $newCSV += @(New-Object -TypeName psobject -Property $props)
}
$newCSV

这是我得到的输出。

Thursday  : True
Sunday    :
taskID    : 1
Saturday  : True
Friday    : True
Tuesday   :
Monday    : True
Wednesday :

Thursday  :
Sunday    :
taskID    : 2
Saturday  :
Friday    : True
Tuesday   :
Monday    : True
Wednesday :

Thursday  : True
Sunday    : True
taskID    : 3
Saturday  : True
Friday    : True
Tuesday   : True
Monday    : True
Wednesday : True

PowerShell输出奇怪,但它都是有组织的。您始终可以使用格式表$newCSV | Format-Table TaskID,Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday -AutoSize。 Export-CSV将保持所有列的正确性。

<强>更新

您始终可以使用switch statement来修改属性。交换$props.$day = $true以获得这样一个好的转换语句:

foreach($DoW in $task.Schedules.Schedule.Days.DayOfWeek){
    foreach($day in $DoW){
        #$props.$day = $true
        switch ($day){
            'Sunday'{$props.Sunday = $true}
            'Monday'{$props.Monday = $true}
            'Tuesday'{$props.Tuesday = $true}
            'Wednesday'{$props.Wednesday = $true}
            'Thursday'{$props.Thursday = $true}
            'Friday'{$props.Friday = $true}
            'Saturday'{$props.Saturday = $true}
            default{"$day is not a Day of the Week"}
        }
    }
}

答案 1 :(得分:0)

通常的智慧似乎是你应该将其转换为[XML],但如果有数千个,我怀疑它会在CPU和内存上变得非常沉重。也许其他人会发布该解决方案进行比较。

与此同时:

[regex]$regex = @'
(?ms)\s*<Task ID="(\d+)".+?
\s*<Days>(.+?)
\s*</Days>.+?
\s*</Task>
'@

$text = [IO.File]::ReadAllText('C:\tasks.xml')
&{
$regex.Matches($text) |
foreach {
 $Schedule = 
 new-object psobject -Property @{
                                 taskID = $_.groups[1].value
                                 mon    = 0
                                 tue    = 0
                                 wed    = 0
                                 thur   = 0
                                 fri    = 0
                                 sat    = 0
                                 sun    = 0
                                 }
    switch -Regex ($_.groups[2].value)
    {
     'Monday'    {$Schedule.mon  = 1}
     'Tuesday'   {$Schedule.tue  = 1}
     'Wednesday' {$Schedule.wed  = 1}
     'Thursday'  {$Schedule.thur = 1}
     'Friday'    {$Schedule.fri  = 1}
     'Saturday'  {$Schedule.sat  = 1}
     'Sunday'    {$Schedule.sun  = 1}
     }
   $schedule 
  }
}| select taskID,mon,tue,wed,thur,fri,sat,sun | ft -auto

taskID mon tue wed thur fri sat sun
------ --- --- --- ---- --- --- ---
1        1   0   0    1   1   1   0
2        1   0   0    0   1   0   0
3        1   1   1    1   1   1   1