【问题标题】:Reading, updating and writing XML document with PowerShell使用 PowerShell 读取、更新和写入 XML 文档
【发布时间】:2020-07-06 11:51:14
【问题描述】:

我想读取、更新然后将一个 XML 格式的 Web.config 文件写回磁盘。 我现在的做法是:

[xml]$config = Get-Content -Path $ConfigPath
# Update...
$config.Save($ConfigPath)

问题是它有点搞乱了初始配置格式。我有一些节点,例如:

<add key="DEBUG_API_ABC" value='
{
  "A": {
    "B": "asd",
    "C": "qwe"    
  }
}
'/>

它使它像:

<add key="DEBUG_API_ABC" value=" {   &quot;..."/>

我想按原样保存,保持格式、文本间距,只在更新时注入一些值。有可能吗?

【问题讨论】:

标签: xml powershell formatting config


【解决方案1】:

加载 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 中产生可识别的结构。


关于问题“我可以在属性值中保留" 而不是&amp;quot; 吗?”

不,你不能。原因如下:

当涉及到序列化“特殊”字符(其中 XML 没有很多,但 "' 是两个)时,XML DOM API 是自以为是的。例如,value='something " something' 是有效的 XML,会导致相关节点的 @value 属性在解析后获取 RAM 中的字符串值 something " something

然而,当该字符串再次被序列化时,value="something &amp;quot; something" 100% 完全相同——但为了重现原始布局,解析器需要记住在原始文件中,该特定属性具有单引号分隔符。

这是很多额外的工作,它会减慢解析速度,占用更多内存,并且这样做不会使最终结果更正确。所以解析器通常不会,它们使用同样正确但更容易生成的默认值。

例如,DOM API 对序列化的看法可能是“所有属性都使用双引号作为分隔符,因此属性值中的所有双引号都会被转义”,这完全没问题,因为它会保留数据完整性,这才是最重要的。

它还将所有单引号属性“规范化”为双引号属性,使属性中的 JSON 更难阅读。但问题的一部分在于,将 JSON 存储在 XML 中可能并不是一开始的最佳选择,至少只要您依赖人工编辑器。

【讨论】:

  • 我不修改 JSON 键,我修改了其他键,但是那些在保存过程中受到影响并且它们被缩小。我的问题的主题是保持我在文件中找到的确切格式,仅在某些节点中注入一些值,但主要不是示例中的 JSON 值。
  • @Garbem 我不喜欢把它告诉你,但你不能。克服它。
  • @Garbem XML 不是一种在文件中布置文本的方式。 XML 是一种在文件中存储数据 的方式。加载文件、修改文件并再次存储将保证数据的完整性,这就是 XML 的设计目标。它不能保证“在文本编辑器中一切看起来都和以前一样”——这从来都不是设计目标,而且对于大多数(如果不是全部)XML 解析器来说都是遥不可及的。不要创建内容取决于 XML 文件在文本编辑器中的外观的情况,这是处理此问题的唯一明智方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多