PowerShell怎么解析和操作XML文件

1次阅读

PowerShell原生支持xml解析与操作,依托[xml]类型加速器和System.Xml.XmlDocument对象,可加载、查询、修改、保存XML,支持命名空间处理。

PowerShell怎么解析和操作XML文件

PowerShell 原生支持 XML 解析和操作,主要靠 [xml] 类型加速器和 .netSystem.Xml.XmlDocument 对象。它不依赖外部工具,语法简洁,适合自动化配置、读写 CI/CD 文件(如 .csproj、app.config)、处理 API 返回的 XML 等场景。

加载 XML 文件并解析成对象

[xml] 强制转换读取文件或字符串,PowerShell 会自动构建可导航的对象模型:

  • 使用 Get-Content -Raw 读取整个文件(避免换行截断),再转为 [xml]
  • 节点变成属性,子节点名即属性名;同名多个节点会自动转为数组
  • 文本内容通过 #text 属性访问(仅当节点含纯文本且无子元素时)

示例:

$xml = [xml](Get-Content "config.xml" -Raw) # 获取第一个  的值 $xml.configuration.connectionStrings.add[0].connectionString # 遍历所有  元素 $xml.configuration.connectionStrings.add | ForEach-Object { $_.name }

安全修改 XML 内容(避免直接字符串替换)

直接改字符串易破坏格式或编码,推荐用 dom 方法操作:

  • SelectSinglenode()SelectNodes() 定位节点(支持 XPath)
  • 修改 .InnerText.InnerXml 或属性值(如 .SetAttribute("key", "newVal")
  • 新增节点:用 CreateElement() + appendChild()InsertBefore()
  • 删除节点:调用父节点的 RemoveChild()

示例(更新属性):

$node = $xml.SelectSingleNode("//add[@name='MyDB']") if ($node) { $node.SetAttribute("connectionString", "Server=new;Database=test;") }

保存修改后的 XML(保持格式与编码

直接用 $xml.Save("path.xml") 会丢失缩进,且默认 UTF-8 无 bom。若需保留原始格式或指定编码:

  • XmlWriter 控制缩进、换行、编码(如 UTF-8 with BOM)
  • 简单场景下,先用 Out-File -Encoding utf8BOM 保存字符串(但会丢缩进)
  • 注意:修改后不要用 ConvertTo-Xml —— 它生成的是 PowerShell 对象序列化结果,不是原结构

推荐写法(带缩进+UTF8 BOM):

$settings = New-Object System.Xml.XmlWriterSettings $settings.Indent = $true; $settings.Encoding = [System.Text.UTF8Encoding]::new($true) $writer = [System.Xml.XmlWriter]::Create("config.xml", $settings) $xml.Save($writer); $writer.Close()

处理命名空间(常见坑点)

带命名空间的 XML(如 wpf、MSBuild 文件)必须注册前缀,否则 XPath 查不到节点:

  • 创建 XmlNamespaceManager,用 AddNamespace() 注册前缀(如 "ms""http://schemas.microsoft.com/developer/msbuild/2003"
  • XPath 中使用前缀://ms:Project/ms:PropertyGroup/ms:OutputPath
  • 查询时传入命名空间管理器:$xml.SelectSingleNode($xpath, $nsMgr)

示例:

$nsMgr = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) $nsMgr.AddNamespace("ms", "http://schemas.microsoft.com/developer/msbuild/2003") $node = $xml.SelectSingleNode("//ms:PropertyGroup/ms:OutputPath", $nsMgr)

text=ZqhQzanResources