Question [RESOLU] multiple sous-noeud fichier XML

Plus d'informations
il y a 14 ans 9 mois #9719 par Arnaud
[Edit : Resolu:
J'ai finalement choisi d’écrire le fichier à la volé
voir dernier post]

Bonjour,

J'essaye de remplir un fichier XML, afin de lister des infrastructure réseau (principalement des switch) via powershell et SNMP pour remplir un fichier XML.

Mon problème se situe dans le remplissage du fichier XML, en effet, mon template est le suivant :

[code:1]
<discover version='1.0'>
<switch>
<name></name>
<address></address>
<version></version>
<interfaces>
<interface>
<desc>0</desc>
<type>0</type>
<speed>0</speed>
<mac>0</mac>
<adminstatus></adminstatus>
<operstatus></operstatus>
</interface>
</interfaces>
</switch>
</discover>
[/code:1]

J'essaye donc de remplir les champs à la volé de cette facon :
[code:1]$xml = New-Object XML
$xml.Load($xmlfile)
#$temp = @($xml.discover.switch)[0]
$new = (@($xml.discover.switch)[0]).Clone()
$new.name = \"Switch 1\"
$new.address = \"0.0.0.0\"
$new.version = \"Version 2\"[/code:1]

Ce qui fonctionne bien.

Cependant, j'éprouve des difficultés à créer les différentes interfaces.

Quand ce n'est qu'une seule interface, un :
[code:1]$newint = (@($new.interfaces.interface)[0]).Clone()
$newint.desc = \"1er\"
$newint.type = \"1er\"[/code:1]
fonctionne correctement, mais je n'arrive pas à créer un 2eme sous-noeud \"interface\".

J'ai essayé différent \"AppendChild\" ou \"get_Item\" rien n'y fait.

Pourriez-vous m'indiquer la marche à suivre svp ?

PS: En fichier joint, le script comportant un petit historique de mes essais ...

La pièce jointe write_xml.ps1 est absente ou indisponible



Message édité par: DragoonMaster, à: 30/05/11 09:19<br><br>Message édité par: DragoonMaster, à: 9/06/11 10:57
Pièces jointes :

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 14 ans 9 mois #9720 par Laurent Dardenne
Salut,
une solution, en trichant un peu :P :
[code:1]
#D'après www.vistax64.com/powershell/28838-creati...sing-powershell.html
$xmlfile=\&quot;c:\temp\data.xml\&quot;
[XML]$Data=GC $xmlfile
$Node=switch (@($Data.discover.switch.interfaces.GetEnumerator()).count)
{
0 {Throw \&quot;Impossible de créer un noeud dont le contenu est inconnu\&quot;}
1 {$Data.ImportNode($Data.discover.switch.interfaces.interface,$true)}
{ $_ -ge 2} {$Data.ImportNode($Data.discover.switch.interfaces.interface[0],$true)}
}
$AddedNode=$Data.discover.switch.interfaces.AppendChild($Node)
$AddedNode.desc = \&quot;1\&quot;
$AddedNode.speed = \&quot;125\&quot;
$AddedNode.mac = \&quot;AA-BB-CC\&quot;
$Data.Save($xmlfile)
[/code:1]
Par contre, ici ton fichier doit contenir au moins un noeud interface, car sans XSD associé impossible de créer qq chose d'inconnu.

J'ai une solution avec un xsd, mais elle nécessite un outil du SDK dotnet (xsd.exe), celui ci génére un fichier source csharp que l'on compile en une dll. A partir de là on peut créer des instances dotnet :silly:

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 14 ans 9 mois #9721 par Arnaud
Réponse de Arnaud sur le sujet Re:multiple sous-noeud fichier XML
Merci pour ta solution, j'etudierais ca demain, et je n'oublierais pas d'y aposer mes commentaires, codes finaux et un status \&quot;résolu\&quot; si tel était le cas ..

Concernant l'ajout d'XSD, je préfère éviter d'ajouter \&quot;bcp\&quot; de chose, et surtout des DDL, le fichier XML n'est la que pour avoir un accès au donné sous forme de \&quot;data\&quot;.

La suite du projet, et d'utiliser ces données, pour créer automatiquement une visualisation dans visio (j'aurais d'ailleurs aussi peut être des questions qui se poseront sur ce forum :p).

Concernant le noeud, je pense mettre des valeurs null dans mon template, et combiner le tout avec des clones ...

En tout cas, merci beaucoup de la réponse :)

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 14 ans 9 mois #9725 par Arnaud
Réponse de Arnaud sur le sujet Re:multiple sous-noeud fichier XML
J'arrive bien à créer mes sous-noeud, mais c'est désormais le Clone() qui ne marche plus correctement (voir du tout !).

L'idée final étant de pouvoir avoir une fonction \&quot;Add-node\&quot; et \&quot;Add-interface\&quot;, voici ce que j'ai essayé de faire : (Note, j'ai essayé de \&quot;traduire\&quot; la fonction add-interface qui fonctionne (merci d'ailleurs), pour \&quot;add-node\&quot;, ca ne fonctionne pas non plus, ou j'ai du faire une erreur ..)
[code:1]
$ScriptPath = Split-Path (Get-Variable MyInvocation -Scope 0).Value.MyCommand.Path
$xmlfile = $ScriptPath+'\cisco_discover.xml'

function Create-template($filename)
{
$template = \&quot;
&lt;discover version='1.0'&gt;
&lt;switch&gt;
&lt;name&gt;0&lt;/name&gt;
&lt;address&gt;0&lt;/address&gt;
&lt;version&gt;0&lt;/version&gt;
&lt;interfaces&gt;
&lt;interface&gt;
&lt;desc&gt;0&lt;/desc&gt;
&lt;type&gt;0&lt;/type&gt;
&lt;speed&gt;0&lt;/speed&gt;
&lt;mac&gt;0&lt;/mac&gt;
&lt;adminstatus&gt;0&lt;/adminstatus&gt;
&lt;operstatus&gt;0&lt;/operstatus&gt;
&lt;/interface&gt;
&lt;/interfaces&gt;
&lt;/switch&gt;
&lt;/discover&gt;\&quot;
$template | Out-File $filename
}

Create-template $xmlfile

####################
#[xml]$Config = Get-Content $xmlfile
#$element = $Config.CreateElement(\&quot;interface\&quot;«»)
#$element.setattribute(\&quot;desc\&quot;, \&quot;1er\&quot;«»)
#$Config.get_firstChild().appendchild($element)
#$Config.Save($xmlfile)
####################

###############################
function add-node($xmlfile,$name,$address,$version)
{
$xml = New-Object XML
$xml.Load($xmlfile)
$new = (@($xml.discover.switch)[0]).Clone()
$new.name = $name
$new.address = $address
$new.version = $version
$new # display $new state
$xml.Save($xmlfile)
}
function add-interface($xmlfile,$desc,$type,$speed,$mac,$adminstatus,$operstatus)
{
[XML]$Data=GC $xmlfile
$Node=switch (@($Data.discover.switch.interfaces.GetEnumerator()).count)
{
0 {Throw \&quot;Impossible de créer un noeud dont le contenu est inconnu\&quot;}
1 {$Data.ImportNode($Data.discover.switch.interfaces.interface,$true)}
{ $_ -ge 2} {$Data.ImportNode($Data.discover.switch.interfaces.interface[0],$true)}
}

$AddedNode=$Data.discover.switch.interfaces.AppendChild($Node)
$AddedNode.desc = [string]$desc # Methode \&quot;AppendChild\&quot; needs to have a string to set XmlNode properties
$AddedNode.type = [string]$type
$AddedNode.speed = [string]$speed
$AddedNode.mac = [string]$mac
$AddedNode.adminstatus = [string]$adminstatus
$AddedNode.operstatus = [string]$operstatus
$Data.Save($xmlfile)
}
###############################
add-node $xmlfile \&quot;name\&quot; \&quot;address\&quot; \&quot;version\&quot;
add-interface $xmlfile 1 1 1 1 1 1
add-interface $xmlfile 12 12 12 12 12 12



add-node $xmlfile \&quot;name2\&quot; \&quot;address2\&quot; \&quot;version2\&quot;
add-interface $xmlfile 13 13 13 13 13 13
[/code:1]

Une idée de pourquoi ?

Mon template doit obligatoirement comporter des valeurs vide ?

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 14 ans 9 mois #9731 par Laurent Dardenne
DragoonMaster écrit:

J'arrive bien à créer mes sous-noeud, mais c'est désormais le Clone() qui ne marche plus correctement (voir du tout !).

Non c'est l'usage que tu en fais qui ne marche pas.
Tu clones un objet que tu ne rattaches à rien, donc tu ne fais rien, cqfd.
DragoonMaster écrit:

Concernant l'ajout d'XSD, je préfère éviter d'ajouter \&quot;bcp\&quot; de chose

C'est un choix, la présence d'un XSD t'aurais permis de constater que tu ne pouvais ajouter un noeud sur l'élément switch.
Un New-Node à la rigueur, un Set-Node certainement :
[code:1]
function Set-Node($xmlfile,$name,$address,$version)
{
[XML]$Xml=GC $xmlfile
$Xml.discover.switch.name = $name
$Xml.discover.switch.address = $address
$Xml.discover.switch.version = $version
$xml.Save($xmlfile)
}
[/code:1]
Ensuite, l'usage du fichier à chaque appel ne me semble pas efficient.
Quant au nommage des fonctions, il laisse supposer qu'elles sont génériques, ce qui est loin d'être le cas, car couplé à une seule structure de fichier XML, un Set-DiscoverXMLNode ?
De créer une instance à partir d'une classe dérivée d'un xsd ne porte plus cette ambiguïté.
Tu peux consulter ce DSL autour de XML , la dernière version est dispo ici .
Attention, l'usage de variable entre un module et une session Powershell bride ce DSL :
[code:1]
#Xml Module 4.3
Ipmo XML_Module
$global:Type=\&quot;Global value\&quot;

Function Test($type) {
New-XDocument Types -Encoding \&quot;UTF-16\&quot; {
Type {Name {\&quot;$Type\&quot;} }
}|
Foreach { $_.Declaration.ToString(); $_.ToString()
}
}

Test \&quot;Parameter value\&quot;
# result = Global Value

&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;UTF-16\&quot; standalone=\&quot;yes\&quot;?&gt;
&lt;Types&gt;
&lt;Type&gt;
&lt;Name&gt;Global value&lt;/Name&gt;
&lt;/Type&gt;
&lt;/Types&gt;
[/code:1]
Comme quoi les modules Powershell c'est bien, mais pas pour tout :(<br><br>Message édité par: Laurent Dardenne, à: 2/06/11 15:55

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 14 ans 9 mois #9732 par Arnaud
Réponse de Arnaud sur le sujet Re:multiple sous-noeud fichier XML
Mais du coup, m'est il possible de CREER une \&quot;instance\&quot; discover ?

Le but etant de pouvoir, a l'appel de la fonction, RAJOUTER un noeud discover/switch.

et pour un noeuf discvoer/switch donné, rajouter plusieurs interface.

à l'heure actuelle avec ca :
[code:1]
function add-node($xmlfile,$name,$address,$version)
{
[XML]$Xml=GC $xmlfile
$Xml.discover.switch.name = $name
$Xml.discover.switch.address = $address
$Xml.discover.switch.version = $version
$xml.Save($xmlfile)
}
function add-interface($xmlfile,$desc,$type,$speed,$mac,$adminstatus,$operstatus)
{
[XML]$Data=GC $xmlfile
$Node=switch (@($Data.discover.switch.interfaces.GetEnumerator()).count)
{
0 {Throw \&quot;Impossible de créer un noeud dont le contenu est inconnu\&quot;}
1 {$Data.ImportNode($Data.discover.switch.interfaces.interface,$true)}
{ $_ -ge 2} {$Data.ImportNode($Data.discover.switch.interfaces.interface[0],$true)}
}

$AddedNode=$Data.discover.switch.interfaces.AppendChild($Node)
$AddedNode.desc = [string]$desc # Methode \&quot;AppendChild\&quot; needs to have a string to set XmlNode properties
$AddedNode.type = [string]$type
$AddedNode.speed = [string]$speed
$AddedNode.mac = [string]$mac
$AddedNode.adminstatus = [string]$adminstatus
$AddedNode.operstatus = [string]$operstatus
$Data.Save($xmlfile)
}
###############################
add-node $xmlfile \&quot;name\&quot; \&quot;address\&quot; \&quot;version\&quot;
add-interface $xmlfile 1 1 1 1 1 1
add-interface $xmlfile 12 12 12 12 12 12

add-node $xmlfile \&quot;name2\&quot; \&quot;address2\&quot; \&quot;version2\&quot;
add-interface $xmlfile 13 13 13 13 13 13
[/code:1]

Il me créer 1 noeud, 3 interfaces, et le nom du noeud, corespond à \&quot;name2, address2 et version2\&quot;.

Soit un renommage du premier noeud.

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.049 secondes
Propulsé par Kunena