I have an XML document I'm looping through and downloading a file when it exists and saving it to disk. I want to update the XML file to include the location where I saved the data. How can I best do this?
XML file example:
<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>
My script is as follows for looping through the XML data and saving the file locally.
$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
}
}
The examples I have found all seem to say use CreateElement
methond, example below, but I can't get this to work as $r
in the above example is System.Xml.XmlLinkedNode
and CreateElemnt
only seems to be available for System.Xml.XmlNode
, which would be $Inovices
but I want the element to be inside $Invoice.Invoices.invoice
[xml] $doc = Get-Content($filePath)
$child = $doc.CreateElement("newElement")
$doc.DocumentElement.AppendChild($child)
Any suggestions would be appreciated.The outcome I'd be looking for would be to save the above file with the following content.
<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>
The snippet you found works correctly. $Invoice.Invoices.Invoice
is an array containing XmlLinkedNodes
Use the CreateElement()
with your $Invoice
before your foreach loop.
$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){...}
Inside your foreach you can append the $child
to the Node you actually work on
If($r.Invoice_Hyperlink -ne $null){
$r.appendchild($child)
$InvoiceDate = [datetime]::ParseExact($r.Invoice_Date, 'yyyy-MM-dd', $null)
as you can see, i parsed the date from your xml to be able to use the $InvoiceDate.ToString()
-method
After Building your $destination
-Path you can assign that path to your new node with $r.Local_File = $destination
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments