2017-05-23 2 views
0

J'ai un document XML que je parcours et télécharge un fichier lorsqu'il existe et l'enregistre sur le disque. Je souhaite mettre à jour le fichier XML pour inclure l'emplacement où j'ai enregistré les données. Comment puis-je faire mieux?Ajouter un élément enfant à un élément XML à l'aide de Powershell

XML Exemple de fichier:

<Invoices xmlns="http://example.com/"> 
    <invoice> 
    <ContractorName>TEST contractor</ContractorName> 
    <Invoice_Number>12345</Invoice_Number> 
    <Invoice_Date>2017-05-20</Invoice_Date> 
    <Invoice_Amount>100.00</Invoice_Amount> 
    <Invoice_Hyperlink>https://example.com/path/files/file.pdf</Invoice_Hyperlink> 
    </invoice> 
    <invoice> 
    <ContractorName>TEST contractor 2</ContractorName> 
    <Invoice_Number>98765</Invoice_Number> 
    <Invoice_Date>2017-05-20</Invoice_Date> 
    <Invoice_Amount>1000.00</Invoice_Amount> 
    </invoice> 
</invoices> 

Mon script est la suivante pour une boucle à travers les données XML et enregistrez le fichier localement.

$Invoicesfile = "D:\Download\invoices.xml" 
[xml]$Invoice = Get-Content $Invoicesfile -Raw 

$InvoiceDestinationDir = "D:\Invoices_Downloaded\" 

foreach ($r in $Invoice.Invoices.invoice) 
{ 
    If($r.Invoice_Hyperlink -ne $null){ 

     $Directory = $InvoiceDestinationDir + $r.ContractorName + "\"+ $InvoiceDate.ToString('yyyy') + "\" + $InvoiceDate.ToString('MM-MMM') + "\" + $InvoiceDate.ToString('dd') 

     #Test if destination directory exists and create it if it doesn't 
     if (!(Test-Path $Directory)) 
     { 
      New-Item $Directory -type directory | Out-Null 
     } 
     #set destination to destination directory and files name consisting of Jobcode, 
     $destination = $Directory +"\"+ $r.Invoice_Number +"_" + $r.Invoice_Date + $r.Invoice_Hyperlink.SubString($r.Invoice_Hyperlink.LastIndexOf('.')) 

     Invoke-WebRequest -Uri $r.Invoice_Hyperlink -OutFile $destination 
    } 
} 

Les exemples que j'ai trouvé tous semblent dire l'utilisation CreateElement methond, par exemple ci-dessous, mais je ne peux pas obtenir que cela fonctionne comme $r dans l'exemple ci-dessus est System.Xml.XmlLinkedNode et CreateElemnt semble seulement être disponible pour System.Xml.XmlNode, ce qui serait $Inovices mais je veux l'élément à l'intérieur $Invoice.Invoices.invoice

[xml] $doc = Get-Content($filePath) 
$child = $doc.CreateElement("newElement") 
$doc.DocumentElement.AppendChild($child) 

Toute suggestion serait appreciated.The résultat je rechercherai serait d'enregistrer le fichier ci-dessus avec le contenu suivant.

<Invoices xmlns="http://example.com/"> 
    <invoice> 
    <ContractorName>TEST contractor</ContractorName> 
    <Invoice_Number>12345</Invoice_Number> 
    <Invoice_Date>2017-05-20</Invoice_Date> 
    <Invoice_Amount>100.00</Invoice_Amount> 
    <Invoice_Hyperlink>https://example.com/path/files/file.pdf</Invoice_Hyperlink> 
    <Local_File>D:\Invoices_Downloaded\12345_2017-05-20.pdf</Local_File> 
    </invoice> 
    <invoice> 
    <ContractorName>TEST contractor 2</ContractorName> 
    <Invoice_Number>98765</Invoice_Number> 
    <Invoice_Date>2017-05-20</Invoice_Date> 
    <Invoice_Amount>1000.00</Invoice_Amount> 
    </invoice> 
</invoices> 

Répondre

0

L'extrait que vous avez trouvé fonctionne correctement. $Invoice.Invoices.Invoice est un tableau contenant XmlLinkedNodes

Utilisez le CreateElement() avec votre $Invoice avant votre boucle foreach.

$Invoicesfile = "D:\Download\invoices.xml" 
[xml]$Invoice = Get-Content $Invoicesfile -Raw 

$InvoiceDestinationDir = "D:\Invoices_Downloaded\" 

$child = $Invoice.CreateElement("Local_File") 

foreach ($r in $Invoice.Invoices.Invoice){...} 

l'intérieur de votre foreach vous pouvez ajouter le $child au nœud que vous travaillez réellement sur

If($r.Invoice_Hyperlink -ne $null){ 
     $r.appendchild($child) 
     $InvoiceDate = [datetime]::ParseExact($r.Invoice_Date, 'yyyy-MM-dd', $null) 

comme vous pouvez le voir, je parsé la date de votre xml pour pouvoir utiliser la $InvoiceDate.ToString() -method

Après avoir construit votre $destination -Path vous pouvez attribuer ce chemin à votre nouveau noeud avec $r.Local_File = $destination

+0

Tha nks. Cela fonctionne mais quand je sauvegarde le document en utilisant $ invoice.save() il enregistre seulement le dernier élément Local_File. Quel est le meilleur moyen de sauvegarder les éléments et les fichiers modifiés? Ai-je besoin de sauvegarder après chaque '$ r.appendchild ($ child)' – MarcusMaximus

+0

Je ne suis pas sûr de la bonne méthode que je devrais utiliser mais ce que j'ai fait était de créer un nouvel objet XML '[xml] $ newXML = '< ? xml version = "1.0" encoding = "utf-8"?> ''et à la fin de la boucle importé $ r dans le nouvel objet XMl' $ newXML.DocumentElement.AppendChild ($ newXML.ImportNode ($ r, $ true)) | Out-Null' puis sauvegardez le fichier '$ newXML.Save ($ Invoicesfile)' – MarcusMaximus