更改属性值的一部分 [英] Change part of an attribute value
问题描述
我想使用 Powershell 更改 web.config
文件中连接字符串的一部分.
我可以使用以下代码读取所需的连接字符串:
[xml]$XmlDoc = Get-Content C:\...\Web.config$ConString = $XmlDoc.configuration.connectionStrings.add.connectionString[0]
并提取正确的值:
<前>服务器=testDB01\sql14;uid=abc;pwd=def;database=ghi;language=english现在我想更改="之后的部分以根据需要调整值.我可以通过将文本分成部分来访问这些值,例如
$ConString.Split(";")[0].Split("\")[1]
返回
<前>sql14我现在如何更改该值并将其保存到文件中?
这是一个使用 -replace
运算符 来替换连接字符串中的数据库名称:
有关下面 -regex
使用的正则表达式的说明,请参阅 https://regex101.com/r/Va3XN7/1 - 请注意,这是否有效取决于您浏览器的 JavaScript 引擎;例如,它适用于 Chrome,但可能不适用于 Firefox.PowerShell 使用 .NET 正则表达式,在本例中,其行为与(现代)JavaScript 相同.
注意:
正如 Ansgar Wiechers 在评论中指出的那样,点符号 深入到 XML 文档(例如,
$XmlDoc.configuration.connectionStrings.add.connectionString[0]
)很方便,但有局限性:它不适合对 XML 文档进行结构性更改.- 要执行结构更改,您必须直接使用基础
System.Xml.XmlNode
[-derived] 类型.
- 要执行结构更改,您必须直接使用基础
但是,对于简单的非结构性更改(包括这种情况),点表示法可用于进行更新,即:
- 更改 leaf 元素的文本内容.
- 更改属性(层次结构中的任何位置)的值 - 如本例所示.
点表示法的一个普遍缺陷是可能与基础类型的成员发生名称冲突 - 请参阅这个答案.
# 创建一个示例 XML 文件.@'<?xml version="1.0"?><配置><连接字符串><添加><connectionString server="server=testDB01\sql14;uid=abc;pwd=def;database=ghi;language=english"/><connectionString server="..."/></添加></connectionStrings></配置>'@ >测试文件# 将文件读入 XML 文档.[xml] $xmlDoc = Get-Content -Raw test.xml# 更新第一个的'server'属性;元素:# 用'sql999'替换现有的数据库名称$element = $xmlDoc.configuration.connectionStrings.add.connectionString[0]$element.server = $element.server -replace '(?<=\bserver=.+?\\).+?(?=;)', 'sql999'# 将修改后的文档保存回文件中.# 注意:这里使用无 BOM 的 UTF-8 编码.# Convert-Path 确保将完整路径传递给 .Save() 方法,# 因为 .NET 的当前目录通常与 PowerShell 的不同$xmlDoc.Save((Convert-Path test.xml))# 输出更新的内容:获取内容 test.xml
以上产生以下结果 - 注意 sql14
是如何被 sql999
替换的:
<配置><连接字符串><添加><connectionString server="server=testDB01\sql999;uid=abc;pwd=def;database=ghi;language=english"/><connectionString server="..."/></添加></connectionStrings></配置>
I want to change a part of a connection string within an web.config
file with Powershell.
I can read the desired connection string with the following code:
[xml]$XmlDoc = Get-Content C:\...\Web.config
$ConString = $XmlDoc.configuration.connectionStrings.add.connectionString[0]
and get the proper value extracted:
server=testDB01\sql14;uid=abc;pwd=def;database=ghi;language=english
Now I want to change the parts after the "=" to adapt the values as needed. I can access the values by spliting the text into part with e.g.
$ConString.Split(";")[0].Split("\")[1]
that returns
sql14
How can I now change that value and save it to the file?
Here's a self-contained example that uses the -replace
operator to replace the database name in your connection string:
For an explanation of the regular expression used with -regex
below, see https://regex101.com/r/Va3XN7/1 - note that whether that works depends on your browser's JavaScript engine; e.g., it works in Chrome, but may not work in Firefox. PowerShell uses .NET regular expressions, which, in this instance, behave the same as (modern) JavaScript's.
Note:
As Ansgar Wiechers points out in a comment, dot notation to drill into an XML document (e.g.,
$XmlDoc.configuration.connectionStrings.add.connectionString[0]
) is convenient, but has limitations: it isn't suited to making structural changes to XML documents.- To perform structural changes, you must work directly with the methods of the underlying
System.Xml.XmlNode
[-derived] types.
- To perform structural changes, you must work directly with the methods of the underlying
However, for simple, non-structural changes (which includes this case), dot notation can be used to make updates, namely:
- Changing the text content of a leaf element.
- Changing the value of an attribute (anywhere in the hierarchy) - as in this case.
A general pitfall with dot notation is the potential for name collisions with the members of the underlying types - see this answer.
# Create a sample XML file.
@'
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add>
<connectionString server="server=testDB01\sql14;uid=abc;pwd=def;database=ghi;language=english" />
<connectionString server="..." />
</add>
</connectionStrings>
</configuration>
'@ > test.xml
# Read the file into an XML document.
[xml] $xmlDoc = Get-Content -Raw test.xml
# Update the 'server' attribute of the first <connectionString> element:
# Replace the existing db name with 'sql999'
$element = $xmlDoc.configuration.connectionStrings.add.connectionString[0]
$element.server = $element.server -replace '(?<=\bserver=.+?\\).+?(?=;)', 'sql999'
# Save the modified document back to the file.
# Note: This uses BOM-less UTF-8 encoding.
# Convert-Path ensures that a full path is passed to the .Save() method,
# because .NET's current directory typically differ from PowerShell's
$xmlDoc.Save((Convert-Path test.xml))
# Output the updated content:
Get-Content test.xml
The above yields the following - note how sql14
was replaced with sql999
:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add>
<connectionString server="server=testDB01\sql999;uid=abc;pwd=def;database=ghi;language=english" />
<connectionString server="..." />
</add>
</connectionStrings>
</configuration>
这篇关于更改属性值的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!