我有一堆XML文件,我需要在节点文本中做一些替换操作。我的代码似乎无法更新<Notes>
节点,因为找不到它。我已经在Notepad ++中检查了XML路径,看起来是正确的。
这是我用来测试的示例XML文件。
<?xml version="1.0" encoding="UTF-8"?>
<OrganisationUnits>
<OrganisationUnitsRow num="21">
<OrganisationId>ORG1</OrganisationId>
<OrganisationName>ORG 1 TEST</OrganisationName>
<Addresses>
<AddressesRow num="1">
<AddressId>E41002</AddressId>
<MainAddress>Y</MainAddress>
</AddressesRow>
</Addresses>
<ContactDetails>
<ContactDetailsRow num="1">
<ContactId>E6366</ContactId>
<ContactCode>OFFICE</ContactCode>
<Main>N</Main>
<Notes>start date 11/03/1994</Notes>
</ContactDetailsRow>
<ContactDetailsRow num="2">
<ContactId>E6367</ContactId>
<ContactCode>WORK</ContactCode>
<Main>N</Main>
<Notes>start date 11/03/1995</Notes>
</ContactDetailsRow>
<ContactDetailsRow num="3">
<ContactId>E6368</ContactId>
<ContactCode>HOME</ContactCode>
<Main>Y</Main>
<Notes>start date - after 11/03/1995</Notes>
</ContactDetailsRow>
<ContactDetailsRow num="4">
<ContactId>E6369</ContactId>
<ContactCode>EMAIL</ContactCode>
<ContactCodeDesc>Email Address</ContactCodeDesc>
<ContactValue>info@yahoo.com</ContactValue>
<StartDate>2000-03-11</StartDate>
<Main>N</Main>
<Notes>more test notes</Notes>
</ContactDetailsRow>
</ContactDetails>
<Sector>P</Sector>
<SectorDesc>Private</SectorDesc>
</OrganisationUnitsRow>
</OrganisationUnits>
这是我的剧本。
#----- get source xml file(e) from the folder below ---#
$path = "C:\Dump\TEST"
$Files = Get-Childitem -path $path -File -include test_file_1.xml -name
# For every file in the folder specified perform a series of actions below
foreach ($File in $Files)
{
Write-Host "=== FILE is $File ===" -ForegroundColor "White"
$xml = [xml](Get-Content $path\$File)
## SectorDesc
# check to ensure that we have got a SectorDesc row
foreach ($OrganisationUnitsRow in $xml.OrganisationUnits.OrganisationUnitsRow)
{
if ($OrganisationUnitsRow.Item('SectorDesc'))
{
$xml.OrganisationUnits.OrganisationUnitsRow.SectorDesc = $xml.OrganisationUnits.OrganisationUnitsRow.SectorDesc.Replace("`b" , "\b") #backspace
$xml.OrganisationUnits.OrganisationUnitsRow.SectorDesc = $xml.OrganisationUnits.OrganisationUnitsRow.SectorDesc.Replace("`f" , "\f") #form feed
}
}
## Notes
# check to ensure that we have got a Notes row
foreach ($ContactDetailsRow in $xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetailsRow)
{
if ($ContactDetailsRow.Item('Notes'))
{
Write-Host "$ContactDetailsRow.Notes"
$xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetailsRow.Notes = $xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetailsRow.Notes.Replace("\" , "\\") #back slash
$xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetailsRow.Notes = $xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetailsRow.Notes.Replace("`b" , "\b") #backspace
}
}
$xml.Save("$path\$File")
}
当脚本运行时,它会抛出错误。
Property 'Notes' cannot be found on this object; make sure it exists and is settable. At C:\Dump\test10.ps1:33 char:8 + $xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetails ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : PropertyAssignmentException Property 'Notes' cannot be found on this object; make sure it exists and is settable. At C:\Dump\test10.ps1:34 char:8 + $xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetails ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : PropertyAssignmentException
我可能很明显,但我不能马上看到它。
答案 0 :(得分:3)
表达式$xml.Organis...ailsRow.Notes
为您提供所有 <Notes>
个节点的<ContactDetailsRow>
子节点(在您的示例4中)。请改用循环变量(并且可以菊花链式Replace()
次调用):
foreach ($ContactDetailsRow in $xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetailsRow)
{
if ($ContactDetailsRow.Item('Notes'))
{
Write-Host "$ContactDetailsRow.Notes"
$ContactDetailsRow.Notes = $ContactDetailsRow.Notes.Replace("\", "\\").Replace("`b", "\b")
}
}
更好的是,直接选择带有XPath表达式的<Notes>
子节点:
$xml.SelectNodes('//ContactDetailsRow/Notes') | ForEach-Object {
$_.'#text' = $_.'#text'.Replace("\", "\\").Replace("`b", "\b")
}
你的代码没有为你的第一个嵌套循环(你犯了同样的错误)抛出相同的错误的原因是你的XML示例只包含一个<SectorDesc>
节点,所以它不会#&# 39;在那里引发问题。