【问题标题】:Add Child Element To XML Element using Powershell使用 Powershell 将子元素添加到 XML 元素
【发布时间】:2017-10-22 21:02:11
【问题描述】:

我有一个 XML 文档,我正在循环访问并在文件存在时下载该文件并将其保存到磁盘。 我想更新 XML 文件以包含我保存数据的位置。我怎样才能最好地做到这一点?

XML 文件示例:

<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>

我的脚本如下,用于循环遍历 XML 数据并在本地保存文件。

$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
   }
}

我发现的例子似乎都说使用CreateElement方法,下面的例子,但我不能让它工作,因为上面例子中的$rSystem.Xml.XmlLinkedNodeCreateElemnt似乎只是可用于System.Xml.XmlNode,即$Inovices,但我希望元素位于$Invoice.Invoices.invoice

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

任何建议都将不胜感激。我要寻找的结果是将上述文件保存为以下内容。

<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>

【问题讨论】:

    标签: xml powershell powershell-3.0


    【解决方案1】:

    您找到的 sn-p 工作正常。 $Invoice.Invoices.Invoice 是一个包含XmlLinkedNodes 的数组

    在 foreach 循环之前使用 CreateElement()$Invoice

    $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){...}
    

    在您的 foreach 中,您可以将 $child 附加到您实际使用的节点

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

    如您所见,我从您的 xml 中解析了日期以便能够使用 $InvoiceDate.ToString()-method

    在构建 $destination-Path 之后,您可以使用 $r.Local_File = $destination 将该路径分配给新节点

    【讨论】:

    • 谢谢。这可行,但是当我使用 $invoice.save() 保存文档时,它只保存最后一个 Local_File 元素。保存修改后的元素和文件的最佳方法是什么。每次$r.appendchild($child)之后需要保存吗?
    • 我不确定我应该使用正确的方法,但我所做的是创建一个新的 XML 对象 [xml]$newXML = '&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;Invoices xmlns="http://example.com/"&gt;&lt;/Invoices&gt;' 并在循环结束时将 $r 导入到新的 XMl 对象 @ 987654333@然后保存文件$newXML.Save($Invoicesfile)
    猜你喜欢
    • 2018-12-07
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2017-03-11
    • 1970-01-01
    相关资源
    最近更新 更多