用CSV中的数据替换多个字符串

时间:2016-12-14 13:06:18

标签: xml powershell csv

我的所有访问点都有一个CSV(包含标题),并希望通过XML Upload将它们添加到Zabbix。

由于我不想手动为每个AP创建XML文件,我将尝试在PowerShell中执行此操作。但是 - 怎么样?

我尝试了(Get-Content .\Template.xml).Replace()ForEach-Object的一些事情,但我还没有成功。

文件名是:

  • AP.csv(AP列表,标题是主机名和IP):

    Hostname;IP
    AP1;10.29.202.101
    AP2;10.29.202.102
    AP3;10.29.202.103
    AP4;10.29.202.104
    Ap5;10.29.202.105
  • Template.xml

    <hosts>
      <host>
        <host>Hostname</host>
        <name>Hostname</name>
        [...]
        <interfaces>
          <interface>
            [...]
            <ip>PIIP</ip>
            [...]
          </interface>
          <interface>
    

    Template.xml有2个字符串称为“主机名”,2个称为“PIIP” - 两个主机名字符串应替换为AP.csv中的1个主机名,并且两个PIIP都应替换为相关的IP。

到目前为止,我的最后一次尝试是:

$a = Import-Csv .\Ap.csv
$APHost = ($a).Hostname
$APIP = ($a).IP
$xml = Get-Content .\Template.xml
foreach ($row in $a) {
    $xml.Replace('Hostname',$APHost).Replace('PIIP',$APIP) |
        Out-File ".\Aps\$row.xml"
}

但是这个以1个XML文件中的所有主机名和所有IP结束。

我希望每个主机最后都有1个XML文件,包含主机名和相关IP。

2 个答案:

答案 0 :(得分:2)

您的主要问题是:

  • 您在循环外的数组变量中存储了AP名称和IP($APHost$APIP

  • 然后在循环中使用这些数组作为整体,而不是逐个引用它们的元素

这是一个修复程序,它只使用$row.Hostname$row.IP来获取适合迭代的值:

$a = Import-Csv -Delimiter ';' .\Ap.csv
$xml = Get-Content -Raw .\Template.xml
foreach ($row in $a) {
    $xml.Replace('Hostname', $row.Hostname).Replace('PIIP', $row.IP) |
      Out-File ".\Aps\$row.xml"
}

但是,您应该考虑使用真正的XML解析来使您的替换更加健壮:

$a = Import-Csv -Delimiter ';' .\Ap.csv
$xmlTmpl = [xml] (Get-Content -Raw .\Template.xml)

foreach ($row in $a) {

  # Find the parent Xml element of the elements to update.
  $parentEl = $xmlTmpl.hosts.host

  # Set the hostnames, by element *name*.
  $parentEl.host = $parentEl.name = $row.Hostname

  # Set the IP addresses, by element *name*
  foreach ($el in $parentEl.interfaces.interface.ChildNodes) {
    if ($el.Name -eq 'ip') { $el.InnerText = $row.IP } 
  }

  # XPath alternative (doesn't work in PowerShell *Core*):
  # foreach ($el in $parentEl.SelectNodes('interfaces/interface/ip'))
  # { 
  #   $el.InnerText = $row.IP
  # }

  # Save to file 
  # Note: This doesn't include an XML header.
  $xmlTmpl.OuterXml | Out-File ".\Aps\$row.xml"
}

请注意文档层次结构中特定位置的特定元素是如何定位的,这是一种更实用的模板实例化方法(没有误报的可能性)。

答案 1 :(得分:1)

示例:

this.$$('#drawerList')