【问题标题】:Powershell script CSV to XMLPowershell 脚本 CSV 到 XML
【发布时间】:2021-10-23 21:29:12
【问题描述】:

您好,我正在尝试将 csv 文件转换为单个 XML 文件

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

预期的 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>

我使用的代码:

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

上述代码运行良好,但为每个客户创建了不同的 XML 文件。

您能否帮我修改此代码以创建一个 XML 文件,该文件将所有客户数据放入一个文件中

-------------在第一个答案后更新了问题 -------------

我已将 set-content 更新为单个文件名,如下所示

Set-Content -LiteralPath 'sample.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>
      </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>

【问题讨论】:

  • 不,它不起作用,我已经用给定解决方案得到的更新结果更新了我的问题
  • 请看我的更新。

标签: xml powershell csv


【解决方案1】:

script block ({ ... }) 传递给Set-Content-LiteralPath 参数是一种称为delay-bind script-block parameters 的技术,在这种情况下,目标参数的值是为每个输入对象计算的 em>,基于脚本块的输出。

  • the answer 中,您从中获取了代码,这正是意图:根据输入对象的属性值,为每个输入对象写入一个不同的文件。

相比之下,您希望为所有输入对象写入一个 单个 输出文件 - 这是典型的 - 为此您只需传递一个 string - 输出文件路径 - 而不是脚本块;例如:

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

如果$ctm.CustomerNumber +'.xml' 是所需的文件名,请使用
Set-Content -LiteralPath ($ctm.CustomerNumber +'.xml') 或 - 通过expandable string:
Set-Content -LiteralPath "$($ctm.CustomerNumber).xml"


此外,要按照您的问题所示构建输出 XML,您需要首先收集所有展开的客户模板,然后在展开 文档时将它们用作单个数组 em> 模板,在循环之外。然后可以将结果发送到文件:

$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

【讨论】:

    猜你喜欢
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多