【问题标题】:Creating a custom XML from a hash table从哈希表创建自定义 XML
【发布时间】:2021-04-16 20:28:50
【问题描述】:

在过去的几周里,我已经阅读了一些关于我的问题主题的非常有趣的帖子,并且已经接近了,但我需要一个非常具体的 XML,它是从我通过将 CSV 与输出的 Active Directory 比较而创建的哈希表创建的包含特定用户数据的 csv。
具体字段如下:XrefCode、EmployeeNumber、FirstName、LastName、BusinessEmail、StartDate。 我需要输入这些数据的 XML 在格式上非常具体,我找不到让它工作的方法。 这是最终需要的 XML。 所以它必须有一个标题<EmployeeImport>在文档的顶部和</EmployeeImport>在底部,以及在数据的中间<ContactInformation></ContactInformation>

这是我使用的数据示例,非常基本。我的代码到达 AD 并填充电子邮件字段。

号码显示名称状态位置分类帐代码业务电子邮件名字姓氏 1234567 Doe, John 活跃 0GB50 John Doe 2345678 史密斯,简活跃 0GB50 简史密斯

哈希表构建看起来像......

   $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
<EmployeeImport>
 <Employee>
  <XRefCode>1234567</XRefCode>
  <EmployeeNumber>1234567</EmployeeNumber>
  <FirstName>Joe</FirstName>
  <LastName>Doe</LastName>
    <ContactInformation>
     <ContactInformationTypeXrefCode>BusinessEmail</ContactInformationTypeXrefCode>
     <EffectiveStart>2020-04-16</EffectiveStart>
     <ElectronicAddress>JoeDoe@Company.com</ElectronicAddress>
    </ContactInformation>
 </Employee>
 <Employee>
  <XRefCode>2345678</XRefCode>
  <EmployeeNumber>2345678</EmployeeNumber>
  <FirstName>Jane</FirstName>
  <LastName>Smith</LastName>
    <ContactInformation>
     <ContactInformationTypeXrefCode>BusinessEmail</ContactInformationTypeXrefCode>
     <EffectiveStart>2020-04-16</EffectiveStart>
     <ElectronicAddress>Jsmith@Company.com</ElectronicAddress>
    </ContactInformation>
 </Employee>
</EmployeeImport>

我发现的接近的代码是这样的......

$output |% {'<Objects>'} {$_.psobject.properties |% {'<Object>'} {"<$($_.name)>$($_.value)</$($_.name)>"} {'  </Object>'} } {'</Objects>'}

但是,这不会添加所需的页眉和页脚以及 ContactInformation 之间的中间对象。

我可能需要根据我的情况自定义此操作,但我不确定如何构建它。如果是这样的话,有人能指出我正确的方向来为这个特定案例定制这个吗?

谢谢

【问题讨论】:

  • $output 是具有XrefCodeEmployeeNumberFirstName、...等属性的对象的集合?
  • 正确,现在输出是一个带有所需标头的 csv 散列。我可以举个例子。
  • 您能否提供用于将其转换为哈希表的示例数据和代码?以便任何人都可以复制和测试您的案例。
  • 数据已添加到问题中

标签: xml powershell


【解决方案1】:

首先创建一个包含EmployeeImport 根级元素的[xml] 文档:

$xml = [xml]'<EmployeeImport/>'
$emplImport = $xml.DocumentElement

现在您需要将&lt;Employee&gt; 节点添加到每个输入对象的根节点:

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

最后将生成的 xml 文档保存到磁盘:

# Important: only pass full/rooted paths to $xml.Save()
$outputPath = Resolve-Path .\path\to\output.csv

$xml.Save($outputPath)

生成的文件应该是这样的:

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

【讨论】:

  • 这太好了,不过你错过了&lt;ContactInformation&gt;
  • 喜欢这个,走在正确的道路上。错过了圣地亚哥的建议。但这很棒!
【解决方案2】:

这是我对您的问题的处理方法,我更喜欢 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>
"@

【讨论】:

  • 我一直在玩这个,我不断收到以下错误:格式化字符串时出错:索引(从零开始)必须大于或等于零并且小于参数的大小列表.. 在第 4 行 char:1 + @' + ~~ + CategoryInfo : InvalidOperation: ( ...> :String) [], RuntimeException + FullyQualifiedErrorId : FormatError
  • 错误与数据源(您的 csv)有关,而不是代码。我无法使用我发布的示例代码重现此错误。您需要检查您的 csv。 @杰夫
  • 哦,我想我可能正在做点什么。忘记最后的回应。 csv 中有 7 个属性,如果使用 0,则表示有 8 个。一个字段静态为“0”。现在我只需要弄清楚导出,我就可以测试了。这是非常接近的!谢谢
  • @Jeff 实际上在您的原始帖子中的 csv 中有 8 个属性,现在我看到 IsForSystemCommunication 似乎已从您的 PSObject 中删除。如果您能解释数据的确切来源或给我一个要转换为 XML 的输入数据的实际表示,我可以帮助您。
  • 数据是来自 AD 的合并数据和来自 HR 的 cav。最后,“IsForSystemCommunication”实际上总是 0,所以我把它拿出来,这使属性下降到 7。这​​很有效。然后我为该位置创建并输出变量,然后使用 $xml.Save($Output) 保存 XML。这就像一个魅力!我正要提交这个进行测试。非常感谢您的帮助。 (我没有足够的声望在视觉上加分,但我点击了向上箭头!)
猜你喜欢
  • 2010-10-22
  • 1970-01-01
  • 2014-02-27
  • 2012-07-29
  • 1970-01-01
  • 2019-03-08
  • 2018-08-23
  • 2013-03-05
  • 1970-01-01
相关资源
最近更新 更多