在PowerShell中删除XML节点删除了我需要的额外标记

时间:2017-05-10 14:53:40

标签: xml powershell tags removechild

我有一个XML文件,格式如下:

<?xml version="1.0" encoding="utf-8"?>
<factory>
  <map>
    <add key="Audit" assembly="Python.Platform.Core.dll" class="Python.Core.Audit.Services.Audit">
      <parameter name="configFilePath" class="string" value="Config\Audit\AuditConfiguration.xml" />
    </add>
    <add key="Security.Password" assembly="OpenContent.Platform.Core.dll" class="OpenContent.Core.Security.Services.PasswordSecurityMD5">
    </add>
    <add key="Security.Password.Local" assembly="OpenContent.Platform.Core.dll" class="OpenContent.Core.Security.Services.PasswordSecurityMD5">
    </add>
    <add key="Guest.Registration" assembly="OpenContent.Platform.Core.dll" class="OpenContent.Core.Guest.Services.DbGuestRegistration">
      <parameter name="registrationStoredProcedure" class="string" value="AddNewGuest" />
      <parameter name="updateEncodedKeyStoredProcedure" class="string" value="UpdateGuestEncodedKey" />
      <parameter name="unregistrationStoredProcedure" class="string" value="DeleteGuest" />
      <parameter name="DeleteExpiredGuestStoredProcedure" class="string" value="DeleteExpiredGuest" />
      <parameter name="defaultValidDays" class="int" value="30" />
    </add>
  </map>
</factory>

我的目标是删除此部分:

    <add key="Audit" assembly="Python.Platform.Core.dll" class="Python.Core.Audit.Services.Audit">
      <parameter name="configFilePath" class="string" value="Config\Audit\AuditConfiguration.xml" />
    </add>

我正在运行的PowerShell脚本如下:

$path = "C:\testing\myxml.xml"

[Xml]$myxml = Get-Content -Path $path -Raw

$old = $myxml.SelectSingleNode("/factory/map/add[@key='Audit']")

$parent = $old.ParentNode
[void] $parent.RemoveChild($old)

$myxml.save($path)

不幸的是,当我运行它时,它还从任何没有参数子节点的Add节点中删除任何结束标记。因此,它不仅仅是删除我要删除的部分(它正在执行),而是现在看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<factory>
  <map>



    <add key="Security.Password" assembly="OpenContent.Platform.Core.dll" class="OpenContent.Core.Security.Services.PasswordSecurityMD5">

    <add key="Security.Password.Local" assembly="OpenContent.Platform.Core.dll" class="OpenContent.Core.Security.Services.PasswordSecurityMD5">

    <add key="Guest.Registration" assembly="OpenContent.Platform.Core.dll" class="OpenContent.Core.Guest.Services.DbGuestRegistration">
      <parameter name="registrationStoredProcedure" class="string" value="AddNewGuest" />
      <parameter name="updateEncodedKeyStoredProcedure" class="string" value="UpdateGuestEncodedKey" />
      <parameter name="unregistrationStoredProcedure" class="string" value="DeleteGuest" />
      <parameter name="DeleteExpiredGuestStoredProcedure" class="string" value="DeleteExpiredGuest" />
      <parameter name="defaultValidDays" class="int" value="30" />
    </add>
  </map>
</factory>

有关如何在不删除额外结束标记的情况下运行此建议的任何建议吗?

1 个答案:

答案 0 :(得分:1)

这似乎是XmlElement.WriteTo()和类似方法的默认行为 - 对任何没有内部非xml内容的叶元素使用shortform标记。

确定此方法的方法是每个元素的inspecting the IsEmpty property,因此您可以通过在调用IsEmpty之前将$false设置为Save()来欺骗作者保留longform标记:

# Locate all <add /> nodes with no child elements
$addLeafNodes = $myxml.SelectNodes('//add[not(child::*)]')

# Loop through them
foreach($node in $AddLeafNodes){
    # Set IsEmpty property to false
    $node.IsEmpty = $false
}

# Save document
$myxml.Save($path)