【问题标题】:Build XML file based off CSV list using Powershell使用 Powershell 基于 CSV 列表构建 XML 文件
【发布时间】:2021-04-04 21:25:47
【问题描述】:

我有一个 CSV 文件,其布局如下所示:

Region,Store,Number,IP Address,Store Number
Central,ABC,111,127.0.0.1,1234
Central,CDE,222,127.0.0.1,5678
Central,EFG,333,127.0.0.1,9101
Central,HIJ,444,127.0.0.1,1213
Central,KLM,555,127.0.0.1,1415

我需要构建一个如下所列的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_271" class="java.beans.XMLDecoder">
 <object class="client.remoteaccess.model.AddressBookEntry">
  <void property="country">
   <string>USA</string>
  </void>
  <void property="ipAddress">
   <string>127.0.0.1</string>
  </void>
  <void property="name">
   <string>111 ABC</string>
  </void>
  <void property="storeNumber">
   <string>1234</string>
  </void>
 </object>
 <object class="client.remoteaccess.model.AddressBookGroup">
  <void property="name">
   <string>[None]</string>
  </void>
 </object>
 <object class="client.remoteaccess.model.AddressBookGroup">
  <void property="name">
   <string>Imported Entries</string>
  </void>
 </object>
 <object class="client.remoteaccess.model.AddressBookGroup">
  <void property="name">
   <string>Duplicated Entries</string>
  </void>
 </object>
</java>

我需要从 CSV 文件中提取每一行并将其添加到 xml 的中间,应该看起来像这样。

顶部:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_271" class="java.beans.XMLDecoder">

逐行遍历 CSV 文件,拉出每个位置,中间部分应该是这样的:

 <object class="client.remoteaccess.model.AddressBookEntry">
  <void property="country">
   <string>USA</string>
  </void>
  <void property="ipAddress">
   <string>127.0.0.1</string>
  </void>
  <void property="name">
   <string>111 ABC</string>
  </void>
  <void property="storeNumber">
   <string>1234</string>
  </void>
 </object>
 <object class="client.remoteaccess.model.AddressBookEntry">
  <void property="country">
   <string>USA</string>
  </void>
  <void property="ipAddress">
   <string>127.0.0.1</string>
  </void>
  <void property="name">
   <string>222 CDE</string>
  </void>
  <void property="storeNumber">
   <string>5678</string>
  </void>
 </object>

然后添加 XML 的底部部分,如下所示:

 <object class="client.remoteaccess.model.AddressBookGroup">
  <void property="name">
   <string>[None]</string>
  </void>
 </object>
 <object class="client.remoteaccess.model.AddressBookGroup">
  <void property="name">
   <string>Imported Entries</string>
  </void>
 </object>
 <object class="client.remoteaccess.model.AddressBookGroup">
  <void property="name">
   <string>Duplicated Entries</string>
  </void>
 </object>
</java>

目前这是我一直在处理的代码,它会循环执行,但它是我 CSV 文件中的所有最后存储。在我做对这部分之前,我并不担心添加 XML 的顶部或底部。

$xmlpath = "test.xml"
Add-Type -AssemblyName System.Web

$Stores = Import-Csv -Path "Stores.csv"

    foreach($Loc in $Stores){
        $StoreName = '{0}' -f $Loc.Store
        $Number = '{0}' -f $Loc.Number
        $IP = '{0}' -f $Loc."IP Address"
        $StoreNum = '{0}' -f $Loc."Store Number"


        try {
$entryTemplate = @'
 <object class="client.remoteaccess.model.AddressBookEntry">
  <void property="country">
   <string>USA</string>
  </void>
  <void property="ipAddress">
   <string>$IP</string>
  </void>
  <void property="name">
   <string>$Number $StoreName</string>
  </void>
  <void property="storeNumber">
   <string>$StoreNum</string>
  </void>
 </object>
'@

$xml = $data | ForEach-Object {
    $ExecutionContext.InvokeCommand.ExpandString($entrytemplate)
}
$xml | Out-File $xmlpath
        }
        catch {
            Write-Output $_.Exception.Message
        }
    }

【问题讨论】:

    标签: xml powershell loops csv foreach


    【解决方案1】:

    你可以做到的:

    $GlobalXML=@'
    <?xml version="1.0" encoding="UTF-8"?>
    <java version="1.8.0_271" class="java.beans.XMLDecoder">
     {0}
     <object class="client.remoteaccess.model.AddressBookGroup">
      <void property="name">
       <string>[None]</string>
      </void>
     </object>
     <object class="client.remoteaccess.model.AddressBookGroup">
      <void property="name">
       <string>Imported Entries</string>
      </void>
     </object>
     <object class="client.remoteaccess.model.AddressBookGroup">
      <void property="name">
       <string>Duplicated Entries</string>
      </void>
     </object>
    </java>
    '@
    
    $PartXML=@'
    <object class="client.remoteaccess.model.AddressBookEntry">
      <void property="country">
       <string>USA</string>
      </void>
      <void property="ipAddress">
       <string>{0}</string>
      </void>
      <void property="name">
       <string>{1} {2}</string>
      </void>
      <void property="storeNumber">
       <string>{3}</string>
      </void>
     </object>
    '@
    
    $PartText=""
    
    import-csv "C:\temp\test.csv" | %{
    
    $PartText+=$PartXML -f $_."IP Address", $_.Number, $_.Store, $_."Store Number"
    
    }
    
    $GlobalXML -f $PartText| Out-File "c:\temp\result.xml" -encoding UTF8
    

    【讨论】:

    • 很好的答案,就像一个魅力。很容易遵循您的代码,我非常感谢它
    【解决方案2】:
    param(
       $csvFileName = "d:\tmp\data.csv"
    )
    
    @"
    Region,Store,Number,IP Address,Store Number
    Central,ABC,111,127.0.0.1,1234
    Central,CDE,222,127.0.0.1,5678
    Central,EFG,333,127.0.0.1,9101
    Central,HIJ,444,127.0.0.1,1213
    Central,KLM,555,127.0.0.1,1415
    "@ | out-file $csvFileName
    
    $XMLDocument = [xml]@"
    <?xml version="1.0" encoding="UTF-8"?>
    <java version="1.8.0_271" class="java.beans.XMLDecoder">
    </java>
    "@
    
    $javaNode = $XMLDocument.SelectSingleNode("/java")
    
    Import-Csv -Path $csvFileName | ForEach-Object {
       $objectNode = $javaNode.AppendChild($XMLDocument.CreateElement("object"))
       $objectNodeClassAtribute = $XMLDocument.CreateAttribute("class")
       $objectNodeClassAtribute.Value = "client.remoteaccess.model.AddressBookEntry"
       $objectNode.Attributes.Append($objectNodeClassAtribute)
    
       $voidNode = $objectNode.AppendChild($XMLDocument.CreateElement("void"))
       $voidNodePropertyAtribute = $XMLDocument.CreateAttribute("property")
       $voidNodePropertyAtribute.Value = "Country"
       $voidNode.Attributes.Append($voidNodePropertyAtribute)
    
       $StringNode = $voidNode.AppendChild($XMLDocument.CreateElement("string"))
       $StringNode.InnerText = "USA"
       
       $voidNode = $objectNode.AppendChild($XMLDocument.CreateElement("void"))
       $voidNodePropertyAtribute = $XMLDocument.CreateAttribute("property")
       $voidNodePropertyAtribute.Value = "ipAddress"
       $voidNode.Attributes.Append($voidNodePropertyAtribute)
    
       $StringNode = $voidNode.AppendChild($XMLDocument.CreateElement("string"))
       $StringNode.InnerText = $_."IP Address"
       
       $voidNode = $objectNode.AppendChild($XMLDocument.CreateElement("void"))
       $voidNodePropertyAtribute = $XMLDocument.CreateAttribute("property")
       $voidNodePropertyAtribute.Value = "name"
       $voidNode.Attributes.Append($voidNodePropertyAtribute)
    
       $StringNode = $voidNode.AppendChild($XMLDocument.CreateElement("string"))
       $StringNode.InnerText = "{0} {1}" -f $_.Store, $_.Number
    
       $voidNode = $objectNode.AppendChild($XMLDocument.CreateElement("void"))
       $voidNodePropertyAtribute = $XMLDocument.CreateAttribute("property")
       $voidNodePropertyAtribute.Value = "storeNumber"
       $voidNode.Attributes.Append($voidNodePropertyAtribute)
    
       $StringNode = $voidNode.AppendChild($XMLDocument.CreateElement("string"))
       $StringNode.InnerText = $_."Store Number"
    }
    $XMLDocument.Save("d:\tmp\out.xml")
    

    【讨论】:

    • 两个答案都在这里有效,感谢您提供的建议
    猜你喜欢
    • 2020-05-29
    • 2021-02-20
    • 2013-11-19
    • 2015-04-05
    • 2017-08-13
    • 2014-05-29
    • 2021-12-18
    • 1970-01-01
    • 2013-09-16
    相关资源
    最近更新 更多