简体   繁体   English

Powershell 脚本 CSV 到 XML

[英]Powershell script CSV to XML

Hi I am trying to convert a csv file into a single XML file您好,我正在尝试将 csv 文件转换为单个 XML 文件

CSV Data: CSV 资料:

CustomerNumber,FirstName,LastName,Address_1,Address_2,Address_3,City,State,zip
1,ABC,DEF,Street 1,Area 52,,Madurai,TN,123
2,DEF,GHI,Street 2,Area 53,demo,chennai,TN,321
3,GHI,JKL,Street 3,Area 54,,Bangalore,KA,456
4,JKL,MNO,Street 4,Area 55,demo2,Hyderabad,TA,5654
5,MNO,abc,Street 5,Area 56,,Delhi,DL,766

The expected XML file should be预期的 XML 文件应该是

<Content>
      <Customers>
          <Customer>
            <CustomerNumber>1</CustomerNumber>
            <FirstName>ABC</FirstName>
            <LastName>DEF</LastName>
            <Address_1>Street 1</Address_1>
            <Address_2>Area 52</Address_2>
            <Address_3></Address_3>
            <City>Madurai</City>
            <State>TN</State>
            <Zip>123</Zip>
          </Customer>
          <Customer>
            <CustomerNumber>2</CustomerNumber>
            <FirstName>DEF</FirstName>
            <LastName>GHI</LastName>
            <Address_1>Street 2</Address_1>
            <Address_2>Area 53</Address_2>
            <Address_3>demo</Address_3>
            <City>chennai</City>
            <State>TN</State>
            <Zip>321</Zip>
          </Customer>
          <Customer>
            <CustomerNumber>3</CustomerNumber>
            <FirstName>GHI</FirstName>
            <LastName>JKL</LastName>
            <Address_1>Street 3</Address_1>
            <Address_2>Area 54</Address_2>
            <Address_3></Address_3>
            <City>Bangalore</City>
            <State>KA</State>
            <Zip>456</Zip>
          </Customer>
          <Customer>
            <CustomerNumber>4</CustomerNumber>
            <FirstName>JKL</FirstName>
            <LastName>MNO</LastName>
            <Address_1>Street 4</Address_1>
            <Address_2>Area 55</Address_2>
            <Address_3>demo2</Address_3>
            <City>Hyderabad</City>
            <State>TA</State>
            <Zip>5654</Zip>
          </Customer>
          <Customer>
            <CustomerNumber>5</CustomerNumber>
            <FirstName>MNO</FirstName>
            <LastName>abc</LastName>
            <Address_1>Street 5</Address_1>
            <Address_2>Area 56</Address_2>
            <Address_3></Address_3>
            <City>Delhi</City>
            <State>DL</State>
            <Zip>766</Zip>
          </Customer>
      </Customers>
  </Content>

Code I Used:我使用的代码:

$docTemplate = @'
<Content>
      <Customers>
$($ctms -join "`n")
      </Customers>
  </Content>
'@

$entryTemplate = @'
          <Customer>
            <CustomerNumber>$($ctm.CustomerNumber)</CustomerNumber>
            <FirstName>$($ctm.FirstName)</FirstName>
            <LastName>$($ctm.LastName)</LastName>
            <Address_1>$($ctm.Address_1)</Address_1>
            <Address_2>$($ctm.Address_2)</Address_2>
            <Address_3>$($ctm.Address_3)</Address_3>
            <City>$($ctm.City)</City>
            <State>$($ctm.State)</State>
            <Zip>$($ctm.zip)</Zip>
          </Customer>
'@


Import-Csv "sample.csv" -Delimiter ',' | Group-Object CustomerNumber -ov grp | ForEach-Object {
  $ctms = foreach ($ctm in $_.Group) {
    $ExecutionContext.InvokeCommand.ExpandString($entryTemplate)  
  }

  $ExecutionContext.InvokeCommand.ExpandString($docTemplate)
} | Set-Content -LiteralPath { $ctm.CustomerNumber +'.xml' }

the above code is working fine but creates different XML files for each customer.上面的代码工作正常,但为每个客户创建了不同的 XML 文件。

Could you please help me to modify this code to create an XML file which is having all the customer data into a single file您能否帮我修改此代码以创建一个 XML 文件,该文件将所有客户数据放入一个文件中

--------------Updated the Question after the first Answer ------------- --------------第一个答案后更新了问题------------

I have updated the set-content to a single file name as below我已将设置内容更新为单个文件名,如下所示

Set-Content -LiteralPath 'sample.xml'

still it is not correct it is printing like below仍然不正确,它正在打印如下

<Content>
      <Customers>
          <Customer>
            <CustomerNumber>1</CustomerNumber>
            <FirstName>ABC</FirstName>
            <LastName>DEF</LastName>
            <Address_1>Street 1</Address_1>
            <Address_2>Area 52</Address_2>
            <Address_3></Address_3>
            <City>Madurai</City>
            <State>TN</State>
            <Zip>123</Zip>
          </Customer>
      </Customers>
</Content>
<Content>
      <Customers>
          <Customer>
            <CustomerNumber>2</CustomerNumber>
            <FirstName>DEF</FirstName>
            <LastName>GHI</LastName>
            <Address_1>Street 2</Address_1>
            <Address_2>Area 53</Address_2>
            <Address_3>demo</Address_3>
            <City>chennai</City>
            <State>TN</State>
            <Zip>321</Zip>
          </Customer>
      </Customers>
</Content>
<Content>
      <Customers>
          <Customer>
            <CustomerNumber>3</CustomerNumber>
            <FirstName>GHI</FirstName>
            <LastName>JKL</LastName>
            <Address_1>Street 3</Address_1>
            <Address_2>Area 54</Address_2>
            <Address_3></Address_3>
            <City>Bangalore</City>
            <State>KA</State>
            <Zip>456</Zip>
          </Customer>
      </Customers>
</Content>
<Content>
      <Customers>
          <Customer>
            <CustomerNumber>4</CustomerNumber>
            <FirstName>JKL</FirstName>
            <LastName>MNO</LastName>
            <Address_1>Street 4</Address_1>
            <Address_2>Area 55</Address_2>
            <Address_3>demo2</Address_3>
            <City>Hyderabad</City>
            <State>TA</State>
            <Zip>5654</Zip>
          </Customer>
      </Customers>
</Content>
<Content>
      <Customers>
          <Customer>
            <CustomerNumber>5</CustomerNumber>
            <FirstName>MNO</FirstName>
            <LastName>abc</LastName>
            <Address_1>Street 5</Address_1>
            <Address_2>Area 56</Address_2>
            <Address_3></Address_3>
            <City>Delhi</City>
            <State>DL</State>
            <Zip>766</Zip>
          </Customer>
      </Customers>
</Content>

Passing a script block ( {... } ) to Set-Content 's -LiteralPath parameter is a technique known as delay-bind script-block parameters , in which case the target parameter's value is calculated for each input object , based on the script block's output.脚本块( {... } ) 传递给Set-Content-LiteralPath参数是一种称为延迟绑定脚本块参数的技术,在这种情况下,会根据脚本块的 output。

  • In the answer you took the code from, that is the very intent: write to a different file for each input object, based on a property value of the input object.在您从中获取代码的答案中,这正是意图:根据输入 object 的属性值,为每个输入 object 写入不同的文件。

By contrast, you want to write to a single output file for all input objects - as is typical - and for that you simply pass a string - the output file path - rather than a script block;相比之下,您希望为所有输入对象写入单个output 文件——这很典型——为此您只需传递一个字符串——output 文件路径——而不是脚本块; eg:例如:

... | Set-Content -LiteralPath AllCustomers.xml

If $ctm.CustomerNumber +'.xml' is the desired file name, use如果$ctm.CustomerNumber +'.xml'是所需的文件名,请使用
Set-Content -LiteralPath ($ctm.CustomerNumber +'.xml') or - via an expandable string : Set-Content -LiteralPath ($ctm.CustomerNumber +'.xml')或 - 通过可扩展字符串
Set-Content -LiteralPath "$($ctm.CustomerNumber).xml"


Additionally, to structure the output XML as shown in your question, you need to collect all expanded customer templates first , and then use them as a single array when expanding the document template, outside the loop.此外,要按照问题中所示构建 output XML,您需要先收集所有扩展的客户模板,然后在循环外扩展文档模板时将它们用作单个数组。 The result can then be sent to a file:然后可以将结果发送到文件:

$docTemplate = @'
<Content>
      <Customers>
$($ctms -join "`n")
      </Customers>
  </Content>
'@

$entryTemplate = @'
          <Customer>
            <CustomerNumber>$($ctm.CustomerNumber)</CustomerNumber>
            <FirstName>$($ctm.FirstName)</FirstName>
            <LastName>$($ctm.LastName)</LastName>
            <Address_1>$($ctm.Address_1)</Address_1>
            <Address_2>$($ctm.Address_2)</Address_2>
            <Address_3>$($ctm.Address_3)</Address_3>
            <City>$($ctm.City)</City>
            <State>$($ctm.State)</State>
            <Zip>$($ctm.zip)</Zip>
          </Customer>
'@


$ctms = Import-Csv "sample.csv" | Group-Object CustomerNumber -ov grp | ForEach-Object {
  foreach ($ctm in $_.Group) {
    $ExecutionContext.InvokeCommand.ExpandString($entryTemplate)  
  }
}

$ExecutionContext.InvokeCommand.ExpandString($docTemplate) |
  Set-Content -LiteralPath AllCustomers.xml

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM