xml样本
<?xml version="1.0" encoding="UTF-8"?>
<CUSTOMERS xml:lang="en">
<CUSTOMER CREATED_DATE="2020-10-16 13:21:09.0" GROUP_ID="" ID="1509999">
<NAME>
<TITLE></TITLE>
<FIRST_NAME>John</FIRST_NAME>
<LAST_NAME>Smith</LAST_NAME>
</NAME>
<GENDER/>
<DATE_OF_BIRTH/>
<CONTACT_DETAILS>
<TELEPHONE MARKETING_OPT_IN="F" TYPE="MOBILE">0123456789</TELEPHONE>
<EMAIL MARKETING_OPT_IN="F">[email protected]</EMAIL>
</CONTACT_DETAILS>
<ATTRIBUTE NAME="theCompany-News and offers on theCompany Womenswear_OPT_EMAIL">T</ATTRIBUTE>
<ATTRIBUTE NAME="Email Soft Opt In_OPT_EMAIL">F</ATTRIBUTE>
<ATTRIBUTE NAME="REGISTERED_ON_WEBSITE">T</ATTRIBUTE>
</CUSTOMER>
</CUSTOMERS>
我继承了Azure Powershell函数,该函数从XML文件构建值列表。我需要添加一些代码来访问此值:
<ATTRIBUTE NAME="Email Soft Opt In_OPT_EMAIL">F</ATTRIBUTE>
这是我到目前为止拥有的Powershell代码
[xml]$xml = Get-Content C:\Users\Jason2\Desktop\XMLfolder\theSample.xml
$xml
$CustomerListFull = @()
foreach ($customer in $xml.CUSTOMERS.CUSTOMER)
{ $BuildList = New-Object -TypeName psobject
$BuildList | Add-Member -MemberType NoteProperty -Name TITLE -Value $customer.NAME.TITLE.Trim()
$BuildList | Add-Member -MemberType NoteProperty -Name FIRSTNAME -Value $customer.NAME.FIRST_NAME.Trim()
$BuildList | Add-Member -MemberType NoteProperty -Name LASTNAME -Value $customer.NAME.LAST_NAME.Trim()
$BuildList | Add-Member -MemberType NoteProperty -Name EMAILCONSENT -Value "0"
$BuildList | Add-Member -MemberType NoteProperty -Name EMAILSOFTOPTIN -Value "2"
if ($customer.ATTRIBUTE.NAME -like "*OPT_EMAIL") {
foreach ($value in $customer.ATTRIBUTE.NAME) {
if ($value -match "theCompany-News and offers on theCompany Womenswear_OPT_EMAIL") {
$BuildList.EMAILCONSENT = "1"
}
if ($value -match "Email Soft Opt In_OPT_EMAIL") {
$BuildList.EMAILSOFTOPTIN = $customer.ATTRIBUTE.'#text'
}
}
}
$CustomerListFull += $BuildList
}
$CustomerListFull
这错误地给了我所有三个“属性名称”值(进入EMAILSOFTOPTIN字段)
TITLE :
FIRSTNAME : John
LASTNAME : Smith
EMAILCONSENT : 1
EMAILSOFTOPTIN : {T, F, T}
我尝试了多种尝试来尝试访问该值,昨天的用户marsze向我展示了很棒的节点,但是我似乎无法使其在我的forloop中正常工作,但我失败了。
$BuildList.EMAILSOFTOPTIN = $customer.SelectNodes("//*[local-name()='ATTRIBUTE'][@NAME='Email Soft Opt In_OPT_EMAIL']").InnerText
$BuildList.EMAILSOFTOPTIN = $customer.[ATTRIBUTE].[NAME='Email Soft Opt In_OPT_EMAIL').InnerText
$nodes = $xml.SelectNodes("//*[local-name()='ATTRIBUTE'][@NAME='Email Soft Opt In_OPT_EMAIL']")
$BuildList.EMAILSOFTOPTIN = $nodes.InnerText
请帮助使我摆脱痛苦
您的代码中存在多个小缺陷。
1.)
$customer.ATTRIBUTE.NAME -like "*OPT_EMAIL"
如果左操作数是一个集合,则结果也是一个集合,即该操作返回true的所有项的集合,在这种情况下,该条件的所有值都NAME
匹配*OPT_EMAIL"
。另外,此检查也是不必要的,因为您稍后将进行另一个文字比较。
2.)
$value -match "Email Soft Opt In_OPT_EMAIL"
-Match
在这里可能不是一个好选择,因为它将正确的值视为正则表达式。在这种情况下它将起作用,但是我认为您想要-eq
3.)
$customer.ATTRIBUTE.'#text'
这将始终返回<ATTRIBUTE>
当前客户所有节点的内部文本的集合,即{T, F, T}
===
这是我的版本,进行了一些其他更改,但这只是个人喜好问题:
[xml]$xml = Get-Content "C:\Users\Jason2\Desktop\XMLfolder\theSample.xml"
# you can build the array directly, like this
# because the += operator on arrays is terribly slow
$customerListFull = @(foreach ($customer in $xml.Customers.Customer) {
# defaults
$emailConsent = 0 # or $false?
$emailSoftOptIn = "2"
# loop attributes
# the "OPT_EMAIL" check is dispensable here
foreach ($attribute in $customer.Attribute) {
# switch is a good replacement for a lot of if's,
# that basically all do the same check
switch ($attribute.Name) {
"theCompany-News and offers on theCompany Womenswear_OPT_EMAIL" {
$emailConsent = 1 # or $true?
}
"Email Soft Opt In_OPT_EMAIL" {
$emailSoftOptIn = switch ($attribute.InnerText.Trim()) {
"F" { 0 }
"T" { 1 }
}
### OR ###
$emailSoftOptIn = @{F = 0; T = 1}[$attribute.InnerText.Trim()]
}
}
}
# Create and output the object directly.
# This is an easier way to construct an object,
# which also keeps the property order
[PSCustomObject]@{
Title = $customer.Name.Title.Trim()
FirstName = $customer.Name.First_Name.Trim()
LastName = $customer.Name.Last_Name.Trim()
EmailConsent = $emailConsent
EmailSoftOptIn = $emailSoftOptIn
}
### OR ###
# use [ordered]
New-Object -TypeName PSObject -Property ([ordered]@{
Title = $customer.Name.Title.Trim()
FirstName = $customer.Name.First_Name.Trim()
LastName = $customer.Name.Last_Name.Trim()
EmailConsent = $emailConsent
EmailSoftOptIn = $emailSoftOptIn
})
})
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句