使用 Powershell 将 XML 元素添加到复杂的 XML 文件
Add XML element to complex XML file with Powershell
Powershell 对我来说是一项非常复杂的远程工作任务。这很难解释,但我会尝试。
我有 XML 结构复杂的文件(这是一个具有 Visual Studio 设置的文件):
<UserSettings>
<ToolsOptions>
<ToolsOptionsCategory RegisteredName="Environment" name="Environment">
</ToolsOptionsCategory>
</ToolsOptions>
</UserSettings>
任务被添加到 "ToolsOptionsCategory" 部分以下子节点:
<ToolsOptionsSubCategory PackageName="VS Setup Composition" RegisteredName="ProductUpdates" name="ProductUpdates">
<PropertyValue name="IsBackground">true</PropertyValue>
</ToolsOptionsSubCategory>
我尝试了 AppendChild 和 CreateElement,但不知道如何添加 "PackageName" 和 "RegistereName" 等属性。目标文件中没有这个子节点,我需要添加它。
如果你能帮我指路,我会很高兴。
提前致谢!保持健康,待在家里:)
为了演示,我使用的是 Here-String
[xml]$xml = @"
<UserSettings>
<ToolsOptions>
<ToolsOptionsCategory RegisteredName="Environment" name="Environment">
</ToolsOptionsCategory>
</ToolsOptions>
</UserSettings>
"@
在现实生活中,您可以使用 [xml]$xml = Get-Content -Path 'D:\config.xml'
从文件中加载它
$node = $xml.UserSettings.ToolsOptions.ToolsOptionsCategory
# update the attributes for this node
$node.SetAttribute("PackageName", "VS Setup Composition")
$node.SetAttribute("RegisteredName", "ProductUpdates")
$node.SetAttribute("name", "ProductUpdates")
# create the new sub node (XmlElement)
$newNode = $xml.CreateElement("PropertyValue")
$newNode.SetAttribute("name", "IsBackground")
$newNode.InnerText = "true"
# add this new subnode to the 'ToolsOptionsCategory' node
$node.AppendChild($newNode)
$xml.Save('D:\newConfig.xml')
结果:
<UserSettings>
<ToolsOptions>
<ToolsOptionsCategory RegisteredName="ProductUpdates" name="ProductUpdates" PackageName="VS Setup Composition">
<PropertyValue name="IsBackground">true</PropertyValue>
</ToolsOptionsCategory>
</ToolsOptions>
</UserSettings>
这里还有另一种方法。我添加了评论来解释该方法。
# Create XML object to load data into
$xml = New-Object -TypeName System.Xml.XmlDocument
# Load in XML file
$xml.Load("test.xml")
# Get root tools node to add children
$toolsRootNode = $xml.UserSettings.ToolsOptions.ToolsOptionsCategory
# Store attributes in a hashtable
$toolsAttributes = [ordered]@{
PackageName="Setup Composition"
RegisteredName="ProductUpdates"
name="ProductUpdates"
}
# Set each attribute from hashtable
$toolsSubNode = $xml.CreateElement("ToolsOptionsSubCategory")
foreach ($kvp in $toolsAttributes.GetEnumerator())
{
$toolsSubNode.SetAttribute($kvp.Key, $kvp.Value)
}
# Create property sub node
$propertyNode = $xml.CreateElement("PropertyValue")
$propertyNode.SetAttribute("name", "IsBackground")
$propertyNode.InnerText = "true"
# Append property node to tools sub node
$toolsSubNode.AppendChild($propertyNode)
# Finally add tools sub node to root node
$toolsRootNode.AppendChild($toolsSubNode)
# Save to new output XML file
$xml.Save("output.xml")
output.xml
<UserSettings>
<ToolsOptions>
<ToolsOptionsCategory RegisteredName="Environment" name="Environment">
<ToolsOptionsSubCategory PackageName="Setup Composition" RegisteredName="ProductUpdates" name="ProductUpdates">
<PropertyValue name="IsBackground">true</PropertyValue>
</ToolsOptionsSubCategory>
</ToolsOptionsCategory>
</ToolsOptions>
</UserSettings>
Powershell 对我来说是一项非常复杂的远程工作任务。这很难解释,但我会尝试。 我有 XML 结构复杂的文件(这是一个具有 Visual Studio 设置的文件):
<UserSettings>
<ToolsOptions>
<ToolsOptionsCategory RegisteredName="Environment" name="Environment">
</ToolsOptionsCategory>
</ToolsOptions>
</UserSettings>
任务被添加到 "ToolsOptionsCategory" 部分以下子节点:
<ToolsOptionsSubCategory PackageName="VS Setup Composition" RegisteredName="ProductUpdates" name="ProductUpdates">
<PropertyValue name="IsBackground">true</PropertyValue>
</ToolsOptionsSubCategory>
我尝试了 AppendChild 和 CreateElement,但不知道如何添加 "PackageName" 和 "RegistereName" 等属性。目标文件中没有这个子节点,我需要添加它。 如果你能帮我指路,我会很高兴。
提前致谢!保持健康,待在家里:)
为了演示,我使用的是 Here-String
[xml]$xml = @"
<UserSettings>
<ToolsOptions>
<ToolsOptionsCategory RegisteredName="Environment" name="Environment">
</ToolsOptionsCategory>
</ToolsOptions>
</UserSettings>
"@
在现实生活中,您可以使用 [xml]$xml = Get-Content -Path 'D:\config.xml'
$node = $xml.UserSettings.ToolsOptions.ToolsOptionsCategory
# update the attributes for this node
$node.SetAttribute("PackageName", "VS Setup Composition")
$node.SetAttribute("RegisteredName", "ProductUpdates")
$node.SetAttribute("name", "ProductUpdates")
# create the new sub node (XmlElement)
$newNode = $xml.CreateElement("PropertyValue")
$newNode.SetAttribute("name", "IsBackground")
$newNode.InnerText = "true"
# add this new subnode to the 'ToolsOptionsCategory' node
$node.AppendChild($newNode)
$xml.Save('D:\newConfig.xml')
结果:
<UserSettings>
<ToolsOptions>
<ToolsOptionsCategory RegisteredName="ProductUpdates" name="ProductUpdates" PackageName="VS Setup Composition">
<PropertyValue name="IsBackground">true</PropertyValue>
</ToolsOptionsCategory>
</ToolsOptions>
</UserSettings>
这里还有另一种方法。我添加了评论来解释该方法。
# Create XML object to load data into
$xml = New-Object -TypeName System.Xml.XmlDocument
# Load in XML file
$xml.Load("test.xml")
# Get root tools node to add children
$toolsRootNode = $xml.UserSettings.ToolsOptions.ToolsOptionsCategory
# Store attributes in a hashtable
$toolsAttributes = [ordered]@{
PackageName="Setup Composition"
RegisteredName="ProductUpdates"
name="ProductUpdates"
}
# Set each attribute from hashtable
$toolsSubNode = $xml.CreateElement("ToolsOptionsSubCategory")
foreach ($kvp in $toolsAttributes.GetEnumerator())
{
$toolsSubNode.SetAttribute($kvp.Key, $kvp.Value)
}
# Create property sub node
$propertyNode = $xml.CreateElement("PropertyValue")
$propertyNode.SetAttribute("name", "IsBackground")
$propertyNode.InnerText = "true"
# Append property node to tools sub node
$toolsSubNode.AppendChild($propertyNode)
# Finally add tools sub node to root node
$toolsRootNode.AppendChild($toolsSubNode)
# Save to new output XML file
$xml.Save("output.xml")
output.xml
<UserSettings>
<ToolsOptions>
<ToolsOptionsCategory RegisteredName="Environment" name="Environment">
<ToolsOptionsSubCategory PackageName="Setup Composition" RegisteredName="ProductUpdates" name="ProductUpdates">
<PropertyValue name="IsBackground">true</PropertyValue>
</ToolsOptionsSubCategory>
</ToolsOptionsCategory>
</ToolsOptions>
</UserSettings>