You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PowerShell创建带属性的多层级XML配置文件

PowerShell 生成带属性层级XML配置文件实现

我计划为自己的小型PowerShell应用开发配置XML文件,为此设计了初始化流程:先轮询获取用户输入,再基于用户输入生成配置文件,主程序启动时直接读取该文件数据即可,无需每次启动都重复询问用户。

需要生成的配置文件结构如下:

<CamInfoSettings>
  <Application>
    <AppFolder>C:\Temp\01</AppFolder>
    <PictureFolder>images</PictureFolder>
    <LogFiles>CamInfo.log</LogFiles>
  </Application>
  <Sections>
    <Count>1</Count>
    <Section id="1">
      <Name>FirstSection Name</Name>
      <Description>FirstSection Description</Description>
      <SectionNetworksCount>2</SectionNetworksCount>
      <FileName>C:\Temp\01\Section1.config</FileName>
      <SectionIpNetworks>
          <SectionIpNetwork id="1">
              <Network>192.168.12.</Network>
              <StartIp>22</StartIp>
              <FinishIp>99</FinishIp>
          </SectionIpNetwork>
          <SectionIpNetwork id="2">
              <Network>192.168.13.</Network>
              <StartIp>1</StartIp>
              <FinishIp>254</FinishIp>
          </SectionIpNetwork>
      </SectionIpNetworks>
    </Section>
</Sections>
</CamInfoSettings>

目前已经掌握基础的XML创建方法,但卡在了SectionIpNetworks节点下添加多个子元素的环节。由于主程序支持使用多个网络,需要严格按照上述结构生成文件,目前可以创建一个或多个网络节点,但无法为这些节点设置"id"属性,也不能在每个网络节点下添加对应的子元素。

已编写的代码如下,后续循环逻辑卡住:

$SectionEnumber = [int]$Configfile.CamInfoSettings.Sections.Count + 1
$Configfile.SelectSingleNode("CamInfoSettings/Sections/Count").InnerText = $SectionEnumber       
$newSectionNode = $Configfile.CamInfoSettings.Sections.AppendChild($Configfile.CreateElement("Section"))
$newSectionNode.SetAttribute("id",$SectionEnumber)
$newSectionName = $newSectionNode.AppendChild($Configfile.CreateElement("Name"))
$newSectionName.AppendChild($Configfile.CreateTextNode($SectionName)) | Out-Null
$newDescription = $newSectionNode.AppendChild($Configfile.CreateElement("Description"))
$newDescription.AppendChild($Configfile.CreateTextNode($SectionDescription)) | Out-Null
$newSegmentsCount = $newSectionNode.AppendChild($Configfile.CreateElement("SectionNetworksCount"))
$newSegmentsCount.AppendChild($Configfile.CreateTextNode($SectionNetworksCount)) | Out-Null
$newFileName = $newSectionNode.AppendChild($Configfile.CreateElement("FileName"))
$newFileName.AppendChild($Configfile.CreateTextNode($WritePath + "\" + "Section$SectionEnumber.config")) | Out-Null
$newSectionNode.AppendChild($Configfile.CreateElement("SectionNetworks")) | Out-Null
$newNetworksNode =  $Configfile.SelectSingleNode("CamInfoSettings/Sections/Section[@id=$SectionEnumber]/SectionNetworks")
$newNetworksNode.SetAttribute("count",$SectionNetworksCount)
foreach ($item in 1..$SectionNetworksCount) {
$newNetworksNode.AppendChild($Configfile.CreateElement("SectionNetwork")) |Out-Null

# 此处需要创建SectionIpNetwork对应的元素,并设置id属性为$item
}

实现代码修正

原有代码存在两个命名不符的基础问题:

  • 目标结构的网段父节点名称为SectionIpNetworks,原代码创建的是SectionNetworks,需修正节点命名
  • 循环内需要创建的子节点名称为SectionIpNetwork,原代码写为SectionNetwork

完整的循环补充代码如下:

# ---------- 修正父节点创建逻辑 ----------
# 替换原代码中创建父节点的两行
$newSectionNode.AppendChild($Configfile.CreateElement("SectionIpNetworks")) | Out-Null
$newNetworksNode =  $Configfile.SelectSingleNode("CamInfoSettings/Sections/Section[@id=$SectionEnumber]/SectionIpNetworks")

# ---------- 提前获取所有网段的用户输入,示例数据可替换为实际轮询逻辑 ----------
$networkConfigList = @()
for ($i=1; $i -le $SectionNetworksCount; $i++) {
    $network = Read-Host "请输入第$i个网段前缀(如192.168.12.)"
    $startIp = Read-Host "请输入第$i个网段起始IP(如22)"
    $finishIp = Read-Host "请输入第$i个网段结束IP(如99)"
    $networkConfigList += @{Network=$network; StartIp=$startIp; FinishIp=$finishIp}
}

# ---------- 循环生成网段节点 ----------
foreach ($item in 1..$SectionNetworksCount) {
    # 创建SectionIpNetwork节点并设置id属性
    $ipNetworkNode = $Configfile.CreateElement("SectionIpNetwork")
    $ipNetworkNode.SetAttribute("id", $item)

    # 拼接Network子节点
    $networkNode = $ipNetworkNode.AppendChild($Configfile.CreateElement("Network"))
    $networkNode.AppendChild($Configfile.CreateTextNode($networkConfigList[$item-1].Network)) | Out-Null

    # 拼接StartIp子节点
    $startIpNode = $ipNetworkNode.AppendChild($Configfile.CreateElement("StartIp"))
    $startIpNode.AppendChild($Configfile.CreateTextNode($networkConfigList[$item-1].StartIp)) | Out-Null

    # 拼接FinishIp子节点
    $finishIpNode = $ipNetworkNode.AppendChild($Configfile.CreateElement("FinishIp"))
    $finishIpNode.AppendChild($Configfile.CreateTextNode($networkConfigList[$item-1].FinishIp)) | Out-Null

    # 将组装完成的网段节点加入父节点
    $newNetworksNode.AppendChild($ipNetworkNode) | Out-Null
}

内容的提问来源于stack exchange,提问作者Владимир Костяник

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 17:36:05