You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PowerShell 4.0向XML添加节点的技术问题求助

向带命名空间的XML添加新节点的解决方案

现有API返回XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccessPermissions xmlns="http://localhost/RESTApi/v1">
  <AccessProfilePermissions/>
  <ReaderSpecialPermissions/>
  <RoomZoneSpecialPermissions>
    <RoomZoneSpecialPermission>
      <RoomZoneNumber>6</RoomZoneNumber>
      <AccessWeeklyProfileNumber>1</AccessWeeklyProfileNumber>
      <ValidFrom>2023-07-13</ValidFrom>
    </RoomZoneSpecialPermission>
</AccessPermissions>

预期结果

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccessPermissions xmlns="http://localhost/RESTApi/v1">
  <AccessProfilePermissions/>
  <ReaderSpecialPermissions/>
  <RoomZoneSpecialPermissions>
    <RoomZoneSpecialPermission>
      <RoomZoneNumber>6</RoomZoneNumber>
      <AccessWeeklyProfileNumber>1</AccessWeeklyProfileNumber>
      <ValidFrom>2023-07-13</ValidFrom>
    </RoomZoneSpecialPermission>
    <RoomZoneSpecialPermission>
      <RoomZoneNumber>7</RoomZoneNumber>
      <AccessWeeklyProfileNumber>1</AccessWeeklyProfileNumber>
      <ValidFrom>2023-07-31</ValidFrom>
    </RoomZoneSpecialPermission>
</AccessPermissions>

当前错误脚本

# API Response to XML Object
$xmlObject = [xml]$apiresponse

# New Permission in XML Format and conver to XML Object
$newxml = "<RoomZoneSpecialPermission><RoomZoneNumber>7</RoomZoneNumber><AccessWeeklyProfileNumber>1</AccessWeeklyProfileNumber><ValidFrom>2023-07-31</ValidFrom></RoomZoneSpecialPermission>"
$newPermissionObject = [xml]$newxml

# Select RoomZoneSpecialPermissions Node
$roomZoneSpecialPermissions = $xmlObject.SelectSingleNode("//a:RoomZoneSpecialPermissions", $xmlObject.DocumentElement.NamespaceURI)

# New RoomZoneSpecialPermission Node
$newPermissionElement = $xmlObject.CreateElement("RoomZoneSpecialPermission", "http://localhost/RESTApi/v1")

# Add Elements to RoomZoneSpecialPermission Node generated above
$newPermissionElement.AppendChild($xmlObject.CreateElement("RoomZoneNumber", "http://localhost/RESTApi/v1")).InnerText = "7"
$newPermissionElement.AppendChild($xmlObject.CreateElement("AccessWeeklyProfileNumber", "http://localhost/RESTApi/v1")).InnerText = "1"
$newPermissionElement.AppendChild($xmlObject.CreateElement("ValidFrom", "http://localhost/RESTApi/v1")).InnerText = "2023-07-31"


$roomZoneSpecialPermissions.Trust.FrameworkPolicy.ClaimsProviders.AppendChild($newPermissionElement)

$modifiedxml = $xmlObject.OuterXml
Write-Output $modifiedxml

遇到的错误

  • 调用AppendChild时出现异常:“要插入的节点来自不同的文档上下文”
  • 找不到SelectSingleNode的重载,参数计数为2

修正后的脚本及说明

问题分析

  1. 命名空间处理错误:SelectSingleNode的第二个参数需要XmlNamespaceManager对象,而非直接传入命名空间字符串。
  2. 节点路径错误:最后一行的$roomZoneSpecialPermissions.Trust.FrameworkPolicy.ClaimsProviders完全不符合原XML结构,应直接对$roomZoneSpecialPermissions调用AppendChild。
  3. 冗余节点对象:脚本中创建的$newPermissionObject未使用,还会导致跨文档上下文问题,直接用原XML对象创建节点即可避免。

修正代码

# API Response to XML Object
$xmlObject = [xml]$apiresponse

# 创建命名空间管理器
$nsManager = New-Object System.Xml.XmlNamespaceManager($xmlObject.NameTable)
$nsManager.AddNamespace("a", $xmlObject.DocumentElement.NamespaceURI)

# 选中目标父节点RoomZoneSpecialPermissions
$roomZoneSpecialPermissions = $xmlObject.SelectSingleNode("//a:RoomZoneSpecialPermissions", $nsManager)

# 创建新的RoomZoneSpecialPermission节点(带命名空间)
$newPermissionElement = $xmlObject.CreateElement("RoomZoneSpecialPermission", $xmlObject.DocumentElement.NamespaceURI)

# 添加子节点并设置文本
$roomZoneNum = $xmlObject.CreateElement("RoomZoneNumber", $xmlObject.DocumentElement.NamespaceURI)
$roomZoneNum.InnerText = "7"
$newPermissionElement.AppendChild($roomZoneNum)

$profileNum = $xmlObject.CreateElement("AccessWeeklyProfileNumber", $xmlObject.DocumentElement.NamespaceURI)
$profileNum.InnerText = "1"
$newPermissionElement.AppendChild($profileNum)

$validFrom = $xmlObject.CreateElement("ValidFrom", $xmlObject.DocumentElement.NamespaceURI)
$validFrom.InnerText = "2023-07-31"
$newPermissionElement.AppendChild($validFrom)

# 将新节点添加到父节点下
$roomZoneSpecialPermissions.AppendChild($newPermissionElement)

# 输出修改后的XML
$modifiedxml = $xmlObject.OuterXml
Write-Output $modifiedxml

简化写法可选

如果觉得逐节点创建麻烦,也可以用ImportNode将外部XML节点导入到当前文档上下文后再添加:

$xmlObject = [xml]$apiresponse
$nsManager = New-Object System.Xml.XmlNamespaceManager($xmlObject.NameTable)
$nsManager.AddNamespace("a", $xmlObject.DocumentElement.NamespaceURI)
$roomZoneSpecialPermissions = $xmlObject.SelectSingleNode("//a:RoomZoneSpecialPermissions", $nsManager)

# 定义新节点XML字符串(需包含命名空间)
$newPermissionXml = @"
<RoomZoneSpecialPermission xmlns="http://localhost/RESTApi/v1">
  <RoomZoneNumber>7</RoomZoneNumber>
  <AccessWeeklyProfileNumber>1</AccessWeeklyProfileNumber>
  <ValidFrom>2023-07-31</ValidFrom>
</RoomZoneSpecialPermission>
"@
$newXmlObj = [xml]$newPermissionXml
# 导入节点到当前文档上下文(第二个参数为true表示递归导入子节点)
$importedNode = $xmlObject.ImportNode($newXmlObj.DocumentElement, $true)
# 添加节点
$roomZoneSpecialPermissions.AppendChild($importedNode)

$modifiedxml = $xmlObject.OuterXml
Write-Output $modifiedxml

内容的提问来源于stack exchange,提问作者Nico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:05:57