1
votes

I can't find the syntax to replace Write-Host with Export-Csv while filtering with Where-Object (a bit like Import-Csv in this example How to export to "non-standard" CSV with Powershell) in this script :

$xml=[xml]@'
<?xml version="1.0" encoding="iso-8859-1"?>
<catalogue>
  <produits>
    <produit id="pdt1" libelle="produit 1" cat="PDT">
      <metas date="2015.07.24">
        <meta code="123456" value="123456"></meta>
        <meta code="789012" value="ghijkl"></meta>
        <meta code="345678" value="mnopqr"></meta>
      </metas>
    </produit>
    <produit id="pdt2" libelle="produit 2" cat="PDT">
      <metas date="2015.07.24">
        <meta code="111111" value="abcdef"></meta>
        <meta code="789012" value="ghijkl"></meta>
        <meta code="345678" value="mnopqr"></meta>
      </metas>
    </produit>
    <produit id="pdt3" libelle="produit 3" cat="PDT">
      <metas date="2015.07.24">
        <meta code="123456" value="123456"></meta>
        <meta code="789012" value="ghijkl"></meta>
        <meta code="345678" value="mnopqr"></meta>
      </metas>
    </produit>
  </produits>
</catalogue>
'@

$out_csv = "C:\out.csv"

$meta_code = "123456"

$produit_code = "pdt1"
$produit=$xml.catalogue.produits.produit | where {$_.id –like "$produit_code"}

$xml.catalogue.produits.produit | where {$_.cat.startsWith("PDT")} | ForEach-Object {
$meta = $xml.SelectSingleNode("//catalogue/produits/produit[@id='$($_.id)']/metas/meta[@code='$meta_code']")
if($meta) {Write-Host "$($_.id),$($_.libelle)"}
}

Update : I really want same output as with Write-Host ie without header and without quotes like this :

pdt1,produit 1
pdt3,produit 3

and not like this

"id","libelle"
"pdt1","produit 1"
"pdt3","produit 3"

1

1 Answers

2
votes

The question is a bit unclear as written, but I'm going to summarize my interpretation of it:

  • You are iterating through XML looking for specific fields.
  • You have a loop wherein you test for conditions to be met, and if so you want to take 2 specific fields and write them out as a row into a CSV.

Export-Csv takes an object or collection of objects and uses the properties in them to create a CSV.

In my opinion, the best way to go about this is to replace Write-Host with the creation of a [PSObject]; that will get returned in each iteration of your ForEach-Object loop, and then the entire collection that's returned from that can be piped directly into Export-CSV:

$xml.catalogue.produits.produit | where {$_.cat.startsWith("PDT")} | ForEach-Object {
    $meta = $xml.SelectSingleNode("//catalogue/produits/produit[@id='$($_.id)']/metas/meta[@code='$meta_code']")
    if($meta) {
        New-Object PSObject -Property @{ id = $_.id ; libelle = $_.libelle }
    }
} | Export-Csv -Path C:\whatever\my.csv -NoTypeInformation

Based on your comment about needing no headers and no quotes, I would do this this way:

$csv = $xml.catalogue.produits.produit | where {$_.cat.startsWith("PDT")} | ForEach-Object {
    $meta = $xml.SelectSingleNode("//catalogue/produits/produit[@id='$($_.id)']/metas/meta[@code='$meta_code']")
    if($meta) {
        New-Object PSObject -Property @{ id = $_.id ; libelle = $_.libelle }
    }
} | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1
$csv = $csv -replace '"',''
$csv | Out-File -FilePath C:\whatever\my.csv

Out-File defaults to Unicode. If you need ASCII add -Encoding Ascii.