从哈希表创建自定义XML

从哈希表创建自定义XML,xml,powershell,Xml,Powershell,在过去的几周里,我已经阅读了一些关于我的问题主题的非常有趣的帖子,并且已经接近了,但是我需要一个从哈希表创建的非常特定的XML,该哈希表是我通过比较CSV和Active directory创建的,Active directory输出带有特定用户数据的CSV。 具体字段有:XrefCode、EmployeeNumber、FirstName、LastName、BusinessEmail、StartDate。 我需要将这些数据放入的XML在格式上非常具体,我找不到一种方法来实现这一点。 下面是XML的

在过去的几周里,我已经阅读了一些关于我的问题主题的非常有趣的帖子,并且已经接近了,但是我需要一个从哈希表创建的非常特定的XML,该哈希表是我通过比较CSV和Active directory创建的,Active directory输出带有特定用户数据的CSV。
具体字段有:XrefCode、EmployeeNumber、FirstName、LastName、BusinessEmail、StartDate。 我需要将这些数据放入的XML在格式上非常具体,我找不到一种方法来实现这一点。 下面是XML的最终形式。 所以在文档的顶部必须有一个标题“<代码> <代码>”,下面是“代码> <代码>底部,以及在数据<代码> <代码>和<代码> <代码> 这是我使用的数据示例,非常基本。我的代码到达AD并填充电子邮件字段

数字显示名称状态位置分类账代码业务电子邮件姓名姓氏 1234567美国能源部,约翰现役0GB50美国能源部 2345678史密斯,简·史密斯

哈希表构建看起来像

   $match = New-Object PSObject
            $match | Add-Member NoteProperty "XRefCode" $first.SamAccountName
            $match | Add-Member NoteProperty "EmployeeNumber" $first.SamAccountName
            $match | Add-Member NoteProperty "FirstName" $first.'First Name'
            $match | Add-Member NoteProperty "LastName" $first.'Last Name'
            $match | Add-Member NoteProperty "ContactInformationTypeXrefCode" 'BusinessEmail'
            $match | Add-Member NoteProperty "EffectiveStart" $TodaysDay
            $match | Add-Member NoteProperty "ElectronicAddress" $second.mail
            $combine += $match
csv如下所示:抱歉,它排列不好

XRefCode EmployeeNumber FirstName   LastName ContactInformationTypeXrefCode EffectiveStart  IsForSystemCommunication    ElectronicAddress
1234567    1234567       Joe          Doe      BusinessEmail         04/16/2021 0   Jdoe@Company.com
2345678    2345678       Jane        Smith     BusinessEmail    04/16/2021  0    Jsmith@Company.com

1234567
1234567
乔
雌鹿
商务电子邮件
2020-04-16
JoeDoe@Company.com
2345678
2345678
简
史密斯
商务电子邮件
2020-04-16
Jsmith@Company.com
我发现很接近的代码是

$output |% {'<Objects>'} {$_.psobject.properties |% {'<Object>'} {"<$($_.name)>$($_.value)</$($_.name)>"} {'  </Object>'} } {'</Objects>'}
$output |%{'}{$\.psobject.properties |%{'}{($\.value)“}{'}}{'}
但是,这并没有为ContactInformation添加所需的页眉和页脚以及中间对象

我可能需要为我的案例定制这个,但我不确定如何构建它。如果是这样的话,有人能给我指出一个正确的方向,为这个特定的案例定制这个吗


谢谢

首先创建一个
[xml]
文档,其中包含
EmployeeImport
根级别元素:

$xml = [xml]'<EmployeeImport/>'
$emplImport = $xml.DocumentElement
生成的文件应如下所示:


1234567
1234567
乔
雌鹿
商务电子邮件
04/16/2021
0
Jdoe@Company.com
2345678
2345678
简
史密斯
商务电子邮件
04/16/2021
0
Jsmith@Company.com

这是我对你的问题的看法,我更喜欢Mathias解决方案,因为它是干净的代码,这很难看,但符合它的目的

$csv=@'
XRefCode,EmployeeNumber,FirstName,LastName,ContactInformationTypeXrefCode,EffectiveStart,IsForSystemCommunication,ElectronicAddress
1234567,1234567,Joe,Doe,BusinessEmail,04/16/2021,0,Jdoe@Company.com,
2345678,2345678,Jane,Smith,BusinessEmail,04/16/2021,0,Jsmith@Company.com
'@|ConvertFrom-Csv

$properties=$csv[0].PSObject.Properties.Name

[xml]$xml=@"
<EmployeeImport>
$(foreach($line in $csv){
@'
 <Employee>
  <XRefCode>{0}</XRefCode>
  <EmployeeNumber>{1}</EmployeeNumber>
  <FirstName>{2}</FirstName>
  <LastName>{3}</LastName>
    <ContactInformation>
     <ContactInformationTypeXrefCode>{4}</ContactInformationTypeXrefCode>
     <EffectiveStart>{5}</EffectiveStart>
     <IsForSystemCommunication>{6}</IsForSystemCommunication>
     <ElectronicAddress>{7}</ElectronicAddress>
    </ContactInformation>
 </Employee>
'@ -f ($properties|%{$line.$_})
})
</EmployeeImport>
"@
$csv=@'
外部代码,员工编号,名字,姓氏,联系人信息类型外部代码,有效开始,用于系统通信,电子地址
12345671234567,乔,能源部,商业电子邮件,2021年4月16日,0,Jdoe@Company.com,
23456782345678,简,史密斯,商业电子邮件,2021年4月16日,0,Jsmith@Company.com
“@|从Csv转换
$properties=$csv[0]。PSObject.properties.Name
[xml]$xml=@”
$(foreach($csv中的行){
@'
{0}
{1}
{2}
{3}
{4}
{5}
{6}
{7}
'@-f($properties |%{$line.$})
})
"@

$output
是具有
XrefCode
EmployeeNumber
FirstName
、。。。等作为属性?正确,现在输出在一个哈希中,该哈希是一个csv,带有所需的标题。我可以举一个例子。你能提供样本数据和用于将其转换为哈希表的代码吗?因此,任何人都可以复制和测试您的案例。添加到问题中的数据这很好,您缺少了
虽然您喜欢这个,但在正确的道路上。错过了圣地亚哥的建议。但这太棒了!我一直在玩这一点,我不断得到以下错误:错误格式化字符串:索引(基于零)必须大于或等于零,小于参数列表的大小。。在第4行char:1++'+~~+CategoryInfo:InvalidOperation:(…>:String)[],RuntimeException+FullyQualifiedErrorId:FormatError错误与数据源(您的csv)相关,而不是与代码相关。我无法使用我发布的示例代码重现此错误。您需要检查您的csv@杰弗,我想我可能有什么发现。忘记最后的回答吧。csv中有7个属性,如果使用0,则表示有8个属性。一个字段静态为“0”。现在我只需要计算出导出,然后我就可以测试了。这是非常接近!!感谢you@Jeff实际上,在您最初的帖子中,csv中有8个属性,现在我看到
IsForSystemCommunication
似乎已从您的
PSObject
中删除。如果您能解释数据的确切来源,或者给我一个要转换为XML的输入数据的实际表示形式,我可以帮助您。数据是来自AD的合并数据和来自HR的cav。最后,“IsForSystemCommunication”实际上始终为0,所以我去掉了它,将属性降到了7。这起作用了。然后我为该位置创建并输出变量,然后使用$XML.Save($output)保存XML。这很有魅力!我将提交此测试。非常感谢你的帮助。(我没有足够的声誉在视觉上添加点数,但我已单击向上箭头!)
$output = Import-Csv .\path\to\objects.csv

foreach($object in $output){
    # Create `<Employee>` node
    $employee = $emplImport.AppendChild($xml.CreateElement('Employee'))
    
    foreach($property in $object.psobject.Properties){
        # Create an xml child-element for each property on the input object
        $childNode = $employee.AppendChild($xml.CreateElement($property.Name))
        $childNode.InnerText = $property.Value
    }
}
# Important: only pass full/rooted paths to $xml.Save()
$outputPath = Resolve-Path .\path\to\output.csv

$xml.Save($outputPath)
$csv=@'
XRefCode,EmployeeNumber,FirstName,LastName,ContactInformationTypeXrefCode,EffectiveStart,IsForSystemCommunication,ElectronicAddress
1234567,1234567,Joe,Doe,BusinessEmail,04/16/2021,0,Jdoe@Company.com,
2345678,2345678,Jane,Smith,BusinessEmail,04/16/2021,0,Jsmith@Company.com
'@|ConvertFrom-Csv

$properties=$csv[0].PSObject.Properties.Name

[xml]$xml=@"
<EmployeeImport>
$(foreach($line in $csv){
@'
 <Employee>
  <XRefCode>{0}</XRefCode>
  <EmployeeNumber>{1}</EmployeeNumber>
  <FirstName>{2}</FirstName>
  <LastName>{3}</LastName>
    <ContactInformation>
     <ContactInformationTypeXrefCode>{4}</ContactInformationTypeXrefCode>
     <EffectiveStart>{5}</EffectiveStart>
     <IsForSystemCommunication>{6}</IsForSystemCommunication>
     <ElectronicAddress>{7}</ElectronicAddress>
    </ContactInformation>
 </Employee>
'@ -f ($properties|%{$line.$_})
})
</EmployeeImport>
"@