使用CSV中的值替换XML文件中的元素值

时间:2016-06-06 21:07:00

标签: xml csv powershell

Stackoverflow你好心思。
我使用powershell用CSV中的伪名替换XML中的值(名称)。 我有两个文件,Real.xml(元素样式)和Fake.csv Real.xml看起来像这样:

<?xml version="1.0"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Node1>
    <Node2>
      <Element1>blahblahblah</Element1>
      <Element2>blahbablahba</Element2>
      <Node3>
        <Node4>
          <ElementIWannaChange>Cena, John</ElementIWannaChange>
          <Element4>2016-02-11T09:04:15</Element4>
        </Node4>
      </Node3>
    </Node2>
  </Node1>
</Data>

Fake.csv看起来像这样:

ID,Fake_first_name,Fake_last_name,First_Name,LastName
16,Sommer,Agar,John,Cena
13,Steve,Hanson,Ben,Cook
103,Bill,Nye,Lynley,Dove

我想要的最终结果是powershell将通过XML替换真实姓名,并使用CSV中相应的虚假名称。给出上述数据的例子,Cena,John将被Agar,Sommer取代。

这是我迄今为止所得到的。

#This script takes the contents of the XML and exchanges the names in order that they appear with names from a CSV in the order that they appear.

#XML
$XMLpath = "D:\Temp\Real.xml"
$XMLnewPath = "D:\Temp\Replaced-Real.xml"
$XMLcontents = [XML] (Get-content $XMLpath)
$Node = $XMLcontents.SelectNodes("/Data/Node1/Node2/Node3/Node4/ElementIWannaChange")

#CSV
$CSVpath = "D:\Temp\Fake.csv"
$CSVcontents = Import-Csv $CSVpath

$i = 0

foreach($individual in $Node)
{
    $field2 = $CSVcontents[$i].first_name
    $field3 = $CSVcontents[$i].last_name
    $individual.'#Text' = "$field3, $field2"
    $i++
}
$XMLcontents.Save($XMLnewPath)

1 个答案:

答案 0 :(得分:0)

循环+索引在这里没有帮助,因为它只会在一行上放置一个随机名称。如果每个真实姓名都有一个特定的假名,那么每次都需要搜索匹配:

#XML
$XMLpath = "D:\Temp\Real.xml"
$XMLnewPath = "D:\Temp\Replaced-Real.xml"
$XMLcontents = [XML] (Get-content $XMLpath)
$Node = $XMLcontents.SelectNodes("/Data/Node1/Node2/Node3/Node4/ElementIWannaChange")

#CSV
$CSVpath = "D:\Temp\Fake.csv"
$CSVcontents = Import-Csv $CSVpath


foreach($individual in $Node)
{
    $last, $first = $individual.'#text' -split ','

    $csvitem = $CSVcontents | Where-Object { ($_.First_Name -eq $first.Trim()) -and ($_.LastName -eq $last.Trim()) }
    if($csvitem) {
        $fakefirst = $csvitem.fake_first_name
        $fakelast = $csvitem.fake_last_name
        $individual.'#Text' = "$fakelast, $fakefirst"
    }

    #Just be sure we don't get false positives because it remembered the last match
    $csvitem = $null
}

$XMLcontents.Save($XMLnewPath)