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?
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.
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)
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)