.net - 如何将 XmlDocument 保存到“格式类似于 Visual Studio”的 .csproj 中,其中空元素保存在单独的行中?
问题描述
目前,我创建了一个 PowerShell 脚本来检查数百个(是的,数百个)Visual Studio 项目并更新参考以保持一致性,从而修复了许多细微的错误。这适用于能够往返99% 的 XML,以便后续在 Visual Studio 中编辑项目文件不会引入其他更改。
但是,使用XmlDocument.Save()
, EMPTY 元素作为一对保存在同一行..
<StartupObject></StartupObject>
..而不是 Visual Studio 项目编辑器将 EMPTY 元素保存在两行之间的方式..
<StartupObject>
</StartupObject>
这会导致初始提交产生不必要的噪音,当程序员从 Visual Studio 中更新项目时,这些噪音将被重置。
如何XmlDocument
使用 Visual Studio [至少截至 2017 年] 使用的相同格式规则保存 [修改]?
目前,保存是使用显式XmlWriter
并XmlWriterSettings
使用以下配置完成的:
$writerSettings = New-Object System.Xml.XmlWriterSettings
$writerSettings.Indent = $true
$writerSettings.IndentChars = $indent # value stolen previously
$writer = [System.Xml.XmlWriter]::Create($path, $writerSettings)
$xml.Save($writer)
如果使用该XmlDocument.PreserveWhitespace
设置,未修改的节点不受影响。但是,在这种情况下,“格式不正确”的条目不是固定的,并且新节点没有应用正确的缩进/格式。
优选地,这可以通过对保存和/或设置的简单修改而不是自定义编写器(脚本在 PowerShell 中)或一些保存后文本操作(因此感觉有点麻烦)来处理。
解决方案
虽然总的来说我认为你不应该使用正则表达式来篡改 XML,但我也找不到 XmlWriter 类中的任何设置会改变写入空元素的样式。
我将其格式化为您想要的方式的唯一方法是让 XmlWriter 写入内存流并-replace
在其上使用正则表达式:
$writerSettings = New-Object System.Xml.XmlWriterSettings
$writerSettings.Indent = $true
$writerSettings.IndentChars = ' '
$writerSettings.Encoding = New-Object System.Text.UTF8Encoding $false # set to UTF-8 No BOM
# create a stream object to write to
$stream = New-Object System.IO.MemoryStream
$writer = [System.Xml.XmlWriter]::Create($stream, $writerSettings)
$writer.WriteStartDocument()
$writer.WriteStartElement("Root")
$writer.WriteElementString("StartupObject", [string]::Empty)
$writer.WriteElementString("AnotherEmptyElement", [string]::Empty)
$writer.WriteEndElement()
$writer.WriteEndDocument()
$writer.Flush()
$writer.Dispose()
# get whatever is written to the stream in a string variable
$xml = [System.Text.Encoding]::Default.GetString(($stream.ToArray()))
# replace self-closing elements: <StartupObject />
# replace empty elements in one line: <StartupObject></StartupObject>
# to the format where opening and closing tags are on separate lines
$format = '$1<$2>{0}$1</$2>' -f [Environment]::NewLine
$xml = $xml -replace '(.*?)<(.*?)\s*/>', $format -replace '(.*?)<(.*?)></(.*?)>', $format
# save do disk
$xml | Out-File -FilePath 'D:\test.xml' -Force -Encoding default
结果:
<?xml version="1.0" encoding="utf-8"?> <Root> <StartupObject> </StartupObject> <AnotherEmptyElement> </AnotherEmptyElement> </Root>
推荐阅读
- python - 如何使用 python 在 google adwords 选择器中正确指定自定义日期范围?
- c - x ^= x & -x; 其中 x 是无符号整数调用 UB?
- list - 如何从给定的一组值生成map的随机值,然后将键和值存储到scala中的单独变量中
- php - 每三个帖子创建一行
- qt - 警告:QObject::startTimer:定时器只能用于以 QThread 启动的线程
- uwp - 如何捕获旋转的图像进行流式传输?
- math - Kaggle 数据集 - 字母和数字的含义
- javascript - 如何在 vue.js 2 中分离父动态类 css
- sql - SQL CONTAINSTABLE - 意外结果
- java - 如何为Java枚举中的抽象方法创建getter方法?