ajout de sous-éléments XML

Avec PowerShell, je veux ajouter plusieurs sous-éléments dans une arborescence XML.
Je sais ajouter un élément, Je sais ajouter un ou plusieurs attributs, mais je ne comprends pas comment ajouter plusieurs éléments.

Une façon serait de écrire un sous-arbre XML en tant que texte
Mais je ne peux pas utiliser cette méthode car les éléments ne sont pas ajoutés à la fois.

Pour ajouter un élément, je le fais:

[xml]$xml = get-content $nomfichier
$newEl = $xml.CreateElement('my_element')
[void]$xml.root.AppendChild($newEl)

Fonctionne très bien. Cela me donne cet arbre XML:

$xml | fc
class XmlDocument
{
  root =
    class XmlElement
    {
      datas =
        class XmlElement
        {
          array1 =
            [
              value1
              value2
              value3
            ]
        }
      my_element =     <-- the element I just added
    }
}

Maintenant, je veux ajouter un sous élément à 'my_element'. J'utilise une méthode similaire:

$anotherEl = $xml.CreateElement('my_sub_element')
[void]$xml.root.my_element.AppendChild($anotherEl) <-- error because $xml.root.my_element is a string
[void]$newEl.AppendChild($anotherEl)               <-- ok
$again = $xml.CreateElement('another_one')
[void]$newEl.AppendChild($again)

Cela donne cet arbre XML (partiellement affiché):

my_element =
  class XmlElement
  {
    my_sub_element =
    another_one =
  }

Ce sont des attributs, pas des sous-éléments.
Les sous-éléments seraient affichés comme ceci:

my_element =
  [
    my_sub_element
    another_one
  ]

Question : Comment ajouter plusieurs sous-éléments, un à la fois?

24
demandé sur Community 2012-06-12 00:48:34

3 réponses

Jetez un oeil à l'exemple suivant :

# 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")

Édité

Remarque: L'utilisation d'un chemin relatif dans Save ne fera pas ce que vous attendez.

39
répondu JPBlanc 2017-05-23 10:31:12

Je préfère créer xml à la main, au lieu d'utiliser API pour le construire nœud par nœud, comme à mon humble avis à la main, il sera beaucoup plus lisible et plus maintable.

Voici un exemple:

$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)
27
répondu Erti-Chris Eelmaa 2015-04-17 08:04:51

Vérifiez cet exemple de code. Il a tout ce dont vous avez besoin pour créer XML à partir de cratch:

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 = 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)
2
répondu Peter 2015-09-13 08:18:48