【问题标题】:implementing trace in an xml generation PowerShell script在 xml 生成 PowerShell 脚本中实现跟踪
【发布时间】:2020-07-07 20:06:58
【问题描述】:

我是 PowerShell 新手,我需要在下面脚本的几个步骤中创建跟踪。

这是 csv 示例(真实的大约有一百万行) 为了进行测试,我删除了第一列中的一个值

UCB63_DATENUM;U6618_FILENAME;UF6E8_CANAL;U65B8_IDRP
7/8/19 22:27;;ML;1367091;
9/11/19 23:03;49453878_ZN_LIQRLVPR_A_V_ML.pdf;ML;106440
9/24/19 21:04;497E585B_ZN_LIQRLVPR_A_V_CS.pdf;CS;1536658
2/12/20 22:12;58453B75_ZN_LIQRLVPR_A_V_ML.pdf;ML;1406091

首先检查整个 CSV,检查列的正确编号和名称

然后在处理过程中检查异常或错误(我认为是try/catch)

我已经改变了一些东西,其中一些不起作用(我找不到原因)

我仍然需要对我的文档进行第一次检查(列数和列名)

如果您尝试在 TITLE 的结果中看到的代码(在我的 xml 中),我会得到一个我没想到的 ')' 如果我删除 U65B8_IDRP 列中的值,则错误不会被捕获并进入 xml

这里是代码

#vARIABLES EN DUR
$FREQUENCE_DECOMPTE     = 'Nom="FREQUENCE_DECOMPTE" Valeur="MENS"'
$LIBELLE_ORGANISME      = 'Nom="LIBELLE_ORGANISME" Valeur="HUMANIS CCN OG"'
$MONTANT_TOTAL          = 'Nom="MONTANT_TOTAL" Valeur="0"'
$POLE                   = 'Nom="POLE" Valeur="1ADP"'
$CODE_ORGANISME         = 'Nom="CODE_ORGANISME" Valeur="1ADP"'

# Paramètre nombre item par xml VALEUR A MODIFIER A 5000
$maxItemsPerXml = 3

#Import du csv et création des différentes collections 
$liste = Import-Csv -path 'c:\temp\testH.csv' -Delimiter ';'
[System.Collections.ArrayList] $DateErrors = @()
[System.Collections.ArrayList] $FileNameErrors = @()
[System.Collections.ArrayList] $CanalErrors = @()
[System.Collections.ArrayList] $NumAssureErrors = @()

#Initiation booléen

foreach($item in $liste)
{
    #Initiation variables booléennes 
    $MyDateIsCorrect = $true
    $MyFileNameIsCorrect = $true
    $MyCanalIsCorrect = $true
    $MyNumAssureIsCorrect = $true

    #Transformations données
    $date = $($item.UCB63_DATENUM -split " ")[0]
    $renommage = % {$item.U6618_FILENAME.Split('.')[0]}

    if([System.String]::IsNullOrEmpty($item.UCB63_DATENUM)) 
        { 
        $MyDateIsCorrect = $false
        $DateErrors.Add($item)
        }

    else   {
            if($date -notmatch "[0-9]{1,2}[\/][0-9]{1,2}[\/][0-9]{1,2}") 
                { 
                $MyDateIsCorrect = $false
                $DateErrors.Add($item) 
                } 
           }
    
    if([System.String]::IsNullOrEmpty($item.U6618_FILENAME)) 
        { 
        $MyFileNameIsCorrect = $false
        $FileNameErrors.Add($item)
        } 
           
    else   { 
             if($item.U6618_FILENAME -notmatch ".+[\.]pdf") 
                { 
                $MyFileNameIsCorrect = $false
                $FileNameErrors.Add($item)
                }
           }      
    
    if([System.String]::IsNullOrEmpty($item.UF6E8_CANAL)) 
        { 
        $MyCanalIsCorrect = $false
        $CanalErrors.Add($item)
        }
    
    if([System.String]::IsNullOrEmpty($item.U65B8_IDRP)) 
        { 
        $MyNumAssureIsCorrect = $false
        $NumAssureErrors.Add($item)
        }



    #Génération output XML
    if($MyDateIsCorrect -and $MyFileNameIsCorrect -and $MyCanalIsCorrect -and $MyNumAssureIsCorrect)
    {
@"
     <Document>
            <Index Nom="TITLE" Valeur="$renommage"/>
            <Index Nom="NO_ASSURE" Valeur="$($item.U65B8_IDRP)"/>
            <Index Nom="DEBUT_PERIODE" Valeur="$RecupDateFinTraitement"/>
            <Index Nom="FIN_PERIODE" Valeur="$RecupDateFin30"/>
            <Index $FREQUENCE_DECOMPTE/>
            <Index $LIBELLE_ORGANISME/>
            <Index $MONTANT_TOTAL/>
            <Index Nom="DATE_GENERATION_DECOMPTE"$RecupDateFinTraitement/>
            <Index $POLE/>
            <Index $CODE_ORGANISME/>
            <Index Nom="ALERTE_MAIL" Valeur="$fin"/>
            <Fichier Nom="$($item.U6618_FILENAME)"/>
        </Document>
"@ 

    # création fichier
    $xmlFile = "C:\Temp\MIG_ERELEVE_MM_$(get-date -f dd-MM-yyyy)_{0:D3}.xml" -f $xmlFileCount
    # création fichier ok
    $CsvColonneEnPlus = import-csv -path 'c:\temp\testH.csv' -Delimiter ';' | Select-Object *,@{Name='Etat';Expression={'OK'}} 

    
    
    # création contenant xml, décla du root node et écriture dans fichier
@"
<?xml version="1.0" encoding="utf-8"?>
<Documents Origine="ERELEVE_HUM">
$($XMLItems -join "`r`n")
</Documents>
"@ | Set-Content -Path $xmlFile -Encoding UTF8 

        # Création fichier OK suite traitement
        #$CsvColonneEnPlus = import-csv -path 'c:\temp\testH.csv' -Delimiter ';' | Select-Object *,@{Name='Etat';Expression={'OK'}} | Export-Csv -path c:\temp\FichierOK.csv -NoTypeInformation

    }
    else
    {
        #ECRIRE DANS LE 5eme FICHIER RECAP AVEC ;KO
    }
}

$DateErrors.ToArray() | Export-Csv -Path c:\temp\DateErrors.csv -NoTypeInformation
$FileNameErrors.ToArray() | Export-Csv -Path c:\temp\FileNameErrors.csv -NoTypeInformation
$CanalErrors.ToArray() | Export-Csv -Path c:\temp\CanalErrors.csv -NoTypeInformation
$NumAssureErrors.ToArray() | Export-Csv -Path c:\temp\NumAssureErrors.csv -NoTypeInformation

我还想使用以下命令将所有“良好处理并将其导出”到一个 csv 文件中,就像我的第一个 csv 文件一样:

$CsvColonneEnPlus = import-csv -path 'c:\temp\testH.csv' -Delimiter ';' | Select-Object *,@{Name='Etat';Expression={'OK'}} 

它可以工作,但我不知道在代码中的什么位置可以捕获正确的值

这是我得到的结果(捕获所有内容)

"UCB63_DATENUM","U6618_FILENAME","UF6E8_CANAL","U65B8_IDRP","Etat"
"08/07/201","457E6659_ZN_LIQRLVPR_A_V_ML.pdf","ML","","OK"
"11/09/2019 22:04","49453878_ZN_LIQRLVPR_A_V_ML.pdf","ML","106440","OK"
"24/09/2019 00:00","497E585B_ZN_LIQRLVPR_A_V_CS","CS","1536658","OK"
"12/02/2020 00:00","","ML","1406091","OK"
"","3D517878_ZN_LIQRLVPR_A_V_ML.pdf","ML","1282640","OK"

【问题讨论】:

  • 在这里循环字符串数据似乎是不可能的
  • 你的 CSV 文件总是有标题吗?
  • 您需要验证日期,还是只是确保它是一个类似日期的字符串?

标签: powershell if-statement while-loop try-catch export-to-csv


【解决方案1】:

如果您的 CSV 文件始终有标题,您可以在移动时验证每一行的每个值。这样,您就可以取消所有最小/最大计算和 while 循环,只需处理 PS 中预先验证的(就长度而言)数组。

比如:

$Liste = Import-CSV -Path .\file.csv -delimiter ";"
Foreach ($ListItem in $Liste){
    try {$ItemDate = get-date $ListItem.UCB63_DATENUM -EA Stop}catch{write-error "fail"} # Validates this is an actual date
    if (-Not ($ListItem.U6618_FILENAME).endswith(".pdf"){Write-Error "Fail, not a pdf";break} # Makes sure filename ends with .pdf
    if ($null -eq $ListItem.UF6E8_CANAL){Write-Error "Item is empty.";break}
    if ($null -eq $ListItem.65B8_IDRP){write-error "Item is empty.";break}
    # < Do the rest of your work here, after you've validated the input data>

这样您可以构建列表,然后在构建输出之前验证每个项目。

如果您仍想构建输出文件名以匹配列表中的项目,您可以通过使用类似以下的文件名来获取项目的索引(假设每个都是唯一的):

$XMLFile = "C:\Temp\TestHH_$($Liste.IndexOf($ListItem)).xml

然后您也可以取消一堆额外的变量创建并内联进行,例如:

$RecupDateFinTraitement = (Get-Date).ToString('dd-MM-yyyy')
$RecupDateFin30 = (get-date 
$RecupDateFinTraitement).AddDays(30).tostring('dd-MM-yyyy')

【讨论】:

  • 抱歉,这篇文章是在我看到您需要对错误进行实际处理之前发布的。为此,只需为您收到的错误添加一个捕获,而不是在测试失败时中断。另一个答案中的数组构建是一个很好的方法。
  • 这取决于您对数据的需求。找到一条无效数据后,您是否关心该行的其余部分,还是只想继续下一行?就个人而言,如果我得到垃圾数据,我不想看到数据有多糟糕,我会把它发回去。用我的方法,一旦某件事失败了,你就会继续下一个。通过日期检查,如果 Get-Date 无法确定日期,它会失败,这也会捕获空条目,您的每个日期样本都会正确验证,并且可以转换为 dd/MM/yyyy。如果您关心每个错误的条目,则需要在退出之前进行每次检查。
【解决方案2】:

如果我正确理解您的要求,我认为下面的代码应该为您提供基本逻辑。由您决定每个 if 语句需要完成哪些工作。

$liste = Import-Csv -path '.\test.csv' -Delimiter ';'
[System.Collections.ArrayList] $DateErrors = @()
[System.Collections.ArrayList] $FileNameErrors = @()
[System.Collections.ArrayList] $ThirdColumnErrors = @()
[System.Collections.ArrayList] $FourthColumnErrors = @()
    
foreach($item in $liste)
{
    $date = $($item.UCB63_DATENUM -split " ")[0]
    if($date -notmatch "[0-9]{1,2}[\/][0-9]{1,2}[\/][0-9]{1,2}") { $DateErrors.Add($item) }

    if($item.U6618_FILENAME -notmatch ".+[\.]pdf") { $FileNameErrors.Add($item) }
    
    if([System.String]::IsNullOrEmpty($item.UF6E8_CANAL)) { $ThirdColumnErrors.Add($item) }
    
    if([System.String]::IsNullOrEmpty($item.U65B8_IDRP)) { $FourthColumnErrors.Add($item) }
}

$DateErrors.ToArray() | Export-Csv -Path .\DateErrors.csv -NoTypeInformation
$FileNameErrors.ToArray() | Export-Csv -Path .\FileNameErrors.csv -NoTypeInformation
$ThirdColumnErrors.ToArray() | Export-Csv -Path .\ThirdColumnErrors.csv -NoTypeInformation
$FourthColumnErrors.ToArray() | Export-Csv -Path .\FourthColumnErrors.csv -NoTypeInformation

【讨论】:

  • 为什么要为任一选项使用正则表达式? $item.EndsWith() 将验证 .pdf 要求,而 Get-Date $item.UCB63_DATENUM 将验证日期。
  • @RobbieCrash 我不知道.EndsWith() 函数,以及对解析器的不合理不信任
  • @HadrienBeaujean 你在哪里看到 Write-Host *** 你需要用创建/附加 csv 的工作替换它
  • @HadrienBeaujean 我的编辑应该会得到你想要的结果
  • @HadrienBeaujean 我使用的逻辑也会检测到一个空单元格
猜你喜欢
  • 2019-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-15
  • 2021-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多