添加XML子元素

添加XML子元素,xml,powershell,Xml,Powershell,使用PowerShell,我想将几个子元素添加到XML树中。 我知道添加一个元素,我知道添加一个或多个属性,但我不知道如何添加多个元素 一种方法是 但是我不能使用这种方法,因为元素不是一次添加的 要添加一个元素,请执行以下操作: [xml]$xml = get-content $nomfichier $newEl = $xml.CreateElement('my_element') [void]$xml.root.AppendChild($newEl) 很好。这给了我这个XML树: $xml

使用PowerShell,我想将几个子元素添加到XML树中。
我知道添加一个元素,我知道添加一个或多个属性,但我不知道如何添加多个元素

一种方法是
但是我不能使用这种方法,因为元素不是一次添加的

要添加一个元素,请执行以下操作:

[xml]$xml = get-content $nomfichier
$newEl = $xml.CreateElement('my_element')
[void]$xml.root.AppendChild($newEl)
很好。这给了我这个XML树:

$xml | fc
class XmlDocument
{
  root =
    class XmlElement
    {
      datas =
        class XmlElement
        {
          array1 =
            [
              value1
              value2
              value3
            ]
        }
      my_element =     <-- the element I just added
    }
}
这些是属性,而不是子元素。
子元素将显示如下:

my_element =
  [
    my_sub_element
    another_one
  ]

问题:如何添加多个子元素,一次添加一个子元素?

查看以下示例:

# Document creation
[xml]$xmlDoc = New-Object system.Xml.XmlDocument
$xmlDoc.LoadXml("<?xml version=`"1.0`" encoding=`"utf-8`"?><Racine></Racine>")

# Creation of a node and its text
$xmlElt = $xmlDoc.CreateElement("Machine")
$xmlText = $xmlDoc.CreateTextNode("Mach1")
$xmlElt.AppendChild($xmlText)

# Creation of a sub node
$xmlSubElt = $xmlDoc.CreateElement("Adapters")
$xmlSubText = $xmlDoc.CreateTextNode("Network")
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)

# Creation of an attribute in the principal node
$xmlAtt = $xmlDoc.CreateAttribute("IP")
$xmlAtt.Value = "128.200.1.1"
$xmlElt.Attributes.Append($xmlAtt)

# Add the node to the document
$xmlDoc.LastChild.AppendChild($xmlElt);

# Store to a file 
$xmlDoc.Save("c:\Temp\Temp\Fic.xml")
#文档创建
[xml]$xmlDoc=New Object system.xml.XmlDocument
$xmlDoc.LoadXml(“”)
#创建节点及其文本
$xmlElt=$xmlDoc.CreateElement(“机器”)
$xmlText=$xmlDoc.CreateTextNode(“Mach1”)
$xmlElt.AppendChild($xmlText)
#创建子节点
$xmlSubElt=$xmlDoc.CreateElement(“适配器”)
$xmlSubText=$xmlDoc.CreateTextNode(“网络”)
$xmlSubElt.AppendChild($xmlSubText)
$xmlElt.AppendChild($xmlSubElt)
#在主节点中创建属性
$xmlAtt=$xmlDoc.CreateAttribute(“IP”)
$xmlAtt.Value=“128.200.1.1”
$xmlett.Attributes.Append($xmlAtt)
#将节点添加到文档中
$xmlDoc.LastChild.AppendChild($xmlElt);
#存储到文件中
$xmlDoc.Save(“c:\Temp\Temp\Fic.xml”)

编辑


备注:.

我更喜欢手工创建xml,而不是使用API逐节点构造它,因为手工创建的xml更具可读性和可维护性

以下是一个例子:

$pathToConfig = $env:windir + "\Microsoft.NET\Framework64\v4.0.30319\Config\web.config"

$xml = [xml] (type $pathToConfig)

[xml]$appSettingsXml = @"
<appSettings>
    <add key="WebMachineIdentifier" value="$webIdentifier" />
</appSettings>
"@


$xml.configuration.AppendChild($xml.ImportNode($appSettingsXml.appSettings, $true))
$xml.Save($pathToConfig)
$pathToConfig=$env:windir+“\Microsoft.NET\Framework64\v4.0.30319\Config\web.Config”
$xml=[xml](键入$pathToConfig)
[xml]$appSettingsXml=@”
"@
$xml.configuration.AppendChild($xml.ImportNode($appsetingsxml.appSettings,$true))
$xml.Save($pathToConfig)

检查此代码示例。它提供了从头开始创建XML所需的一切:

function addElement($e1, $name2, $value2, $attr2)
{
    if ($e1.gettype().name -eq "XmlDocument") {$e2 = $e1.CreateElement($name2)}
    else {$e2 = $e1.ownerDocument.CreateElement($name2)}
    if ($attr2) {$e2.setAttribute($value2,$attr2)}
    elseif ($value2) {$e2.InnerText = "$value2"}
    return $e1.AppendChild($e2)
}

function formatXML([xml]$xml)
{
    $sb = New-Object System.Text.StringBuilder
    $sw = New-Object System.IO.StringWriter($sb)
    $wr = New-Object System.Xml.XmlTextWriter($sw)
    $wr.Formatting = [System.Xml.Formatting]::Indented
    $xml.Save($wr)
    return $sb.ToString()
}
…现在让我们使用这两个函数来创建和显示新的XML对象:

$xml = New-Object system.Xml.XmlDocument
$xml1 = addElement $xml "a"
$xml2 = addElement $xml1 "b"
$xml3 = addElement $xml2 "c" "value"
$xml3 = addElement $xml2 "d" "attrib" "attrib_value"

write-host `nFormatted XML:`r`n`n(formatXML $xml.OuterXml)
结果如下所示:

Formatted XML:

 <?xml version="1.0" encoding="utf-16"?>
<a>
  <b>
    <c>value</c>
    <d attrib="attrib_value" />
  </b>
</a>
格式化的XML:
价值

适用于访问此网站的任何其他人

我遇到问题是因为我的父文档有一个命名空间,并且
ImportNode
正在向导入的xml添加一个空
xmnls=“”
元素,导致我的应用程序出现问题

根据上面的答案扩展。 要解决这个问题,请将其包装在一个虚拟节点中,并从父文档设置名称空间

$pathToConfig = $env:windir + "\Microsoft.NET\Framework64\v4.0.30319\Config\web.config"

$xml = [xml] (type $pathToConfig)
$root = $xml.get_DocumentElement()
$namespaceuri = $root.NamespaceURI

[xml]$appSettingsXml = @"
<Dummy xmlns="$namespaceuri">
    <appSettings>
        <add key="WebMachineIdentifier" value="$webIdentifier" />
    </appSettings>
</Dummy>
"@


$xml.configuration.AppendChild($xml.ImportNode($appSettingsXml.Dummy.appSettings, $true))
$xml.Save($pathToConfig)
$pathToConfig=$env:windir+“\Microsoft.NET\Framework64\v4.0.30319\Config\web.Config”
$xml=[xml](键入$pathToConfig)
$root=$xml.get\u DocumentElement()
$namespaceuri=$root.namespaceuri
[xml]$appSettingsXml=@”
"@
$xml.configuration.AppendChild($xml.ImportNode($appsetingsxml.Dummy.appSettings,$true))
$xml.Save($pathToConfig)

比我现在找到的解决方案要好得多!而且更干净。谢谢。这个很好用。我的问题是,它在控制台上写了很多东西。Debug显示它发生在这一行:$xmlSubElt.AppendChild($xmlSubText),如果我在末尾写“>$null”。如果写入了其他内容,我可以阻止它吗?将
>$null
替换为
| out null
。要禁止输出到控制台,您也可以简单地使用
[void]
作为所有函数调用的前缀,如下所示:
[void]$xmlDoc.LoadXml(…)
。赋值
$var=something
不输出任何东西,但是函数调用在默认情况下确实会生成输出(它们的返回值)。作为函数编写(可能更好地处理名称空间?),如果有名称空间,您知道如何做吗?特别是。请注意,
“@
需要位于行的开头,不允许空白。如果要添加的节点看起来像这样,并且主名称包含点:
,则需要在导入节点中编写如下变量:
$xml.ImportNode($appSettingsXml.{foo.bar.hello.world},$true))
这对我不起作用。运行echo$appSettingsXml不会输出任何内容
Formatted XML:

 <?xml version="1.0" encoding="utf-16"?>
<a>
  <b>
    <c>value</c>
    <d attrib="attrib_value" />
  </b>
</a>
$pathToConfig = $env:windir + "\Microsoft.NET\Framework64\v4.0.30319\Config\web.config"

$xml = [xml] (type $pathToConfig)
$root = $xml.get_DocumentElement()
$namespaceuri = $root.NamespaceURI

[xml]$appSettingsXml = @"
<Dummy xmlns="$namespaceuri">
    <appSettings>
        <add key="WebMachineIdentifier" value="$webIdentifier" />
    </appSettings>
</Dummy>
"@


$xml.configuration.AppendChild($xml.ImportNode($appSettingsXml.Dummy.appSettings, $true))
$xml.Save($pathToConfig)