【问题标题】:Replace not working on XML nodes替换不适用于 XML 节点
【发布时间】:2017-10-20 12:48:27
【问题描述】:

我有一堆 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")
}

脚本运行时会抛出错误。

在此对象上找不到属性“注释”;确保它存在并且是 可设置。 在 C:\Dump\test10.ps1:33 char:8 + $xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetails ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException +fullyQualifiedErrorId:PropertyAssignmentException 在此对象上找不到属性“注释”;确保它存在并且是 可设置。 在 C:\Dump\test10.ps1:34 char:8 + $xml.OrganisationUnits.OrganisationUnitsRow.ContactDetails.ContactDetails ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException +fullyQualifiedErrorId:PropertyAssignmentException

我可能很明显,但我不能马上看到。

【问题讨论】:

    标签: xml powershell replace


    【解决方案1】:

    表达式$xml.Organis...ailsRow.Notes 为您提供所有 &lt;ContactDetailsRow&gt; 节点的&lt;Notes&gt; 子节点(在您的示例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 表达式直接选择 &lt;Notes&gt; 子节点:

    $xml.SelectNodes('//ContactDetailsRow/Notes') | ForEach-Object {
        $_.'#text' = $_.'#text'.Replace("\", "\\").Replace("`b", "\b")
    }
    

    您的代码不会为您的第一个嵌套循环(您犯了同样的错误)抛出相同错误的原因是您的 XML 示例仅包含一个 &lt;SectorDesc&gt; 节点,因此它不会触发问题在那里。

    【讨论】:

    • 感谢@Ansgar Wiechers 解释我的代码错误的原因——很高兴知道错误的原因
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 2018-03-05
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多