加载 XML 文档的正确方法(不仅在 PowerShell 中)是使用 XML 解析器来加载它并避免使用 Get-Content,因为如果有机会,Get-Content 会很高兴地破坏文件编码。
您似乎有一个属性中包含 JSON 数据的 XML 文件,这很奇怪,但让我们使用您所拥有的:
$config = New-Object xml
$config.Load $ConfigPath
$debugApi = $config.selectSingleNode("//add[@key='DEBUG_API_ABC']")
$configData = $debugApi.getAttribute("value") | ConvertFrom-JSON
$configData.A.B = "new value"
$configJson = $configData | ConvertTo-JSON
$debugApi.setAttribute("value", $configJson)
$config.Save($ConfigPath)
ConvertTo-JSON 默认会漂亮地打印其输出,因此虽然它可能不会在 JSON 中保持“原始”空白布局,但仍会在 XML 中产生可识别的结构。
关于问题“我可以在属性值中保留" 而不是" 吗?”
不,你不能。原因如下:
当涉及到序列化“特殊”字符(其中 XML 没有很多,但 " 和 ' 是两个)时,XML DOM API 是自以为是的。例如,value='something " something' 是有效的 XML,会导致相关节点的 @value 属性在解析后获取 RAM 中的字符串值 something " something。
然而,当该字符串再次被序列化时,value="something " something" 100% 完全相同——但为了重现原始布局,解析器需要记住在原始文件中,该特定属性具有单引号分隔符。
这是很多额外的工作,它会减慢解析速度,占用更多内存,并且这样做不会使最终结果更正确。所以解析器通常不会,它们使用同样正确但更更容易生成的默认值。
例如,DOM API 对序列化的看法可能是“所有属性都使用双引号作为分隔符,因此属性值中的所有双引号都会被转义”,这完全没问题,因为它会保留数据完整性,这才是最重要的。
它还将所有单引号属性“规范化”为双引号属性,使属性中的 JSON 更难阅读。但问题的一部分在于,将 JSON 存储在 XML 中可能并不是一开始的最佳选择,至少只要您依赖人工编辑器。