Question
[RESOLU] multiple sous-noeud fichier XML
- Arnaud
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 6
- Remerciements reçus 0
il y a 14 ans 9 mois #9719
par Arnaud
[RESOLU] multiple sous-noeud fichier XML a été créé 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 ...
Message édité par: DragoonMaster, à: 30/05/11 09:19<br><br>Message édité par: DragoonMaster, à: 9/06/11 10:57
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.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 14 ans 9 mois #9720
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:multiple sous-noeud fichier XML
Salut,
une solution, en trichant un peu
:
[code:1]
#D'après www.vistax64.com/powershell/28838-creati...sing-powershell.html
$xmlfile=\"c:\temp\data.xml\"
[XML]$Data=GC $xmlfile
$Node=switch (@($Data.discover.switch.interfaces.GetEnumerator()).count)
{
0 {Throw \"Impossible de créer un noeud dont le contenu est inconnu\"}
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 = \"1\"
$AddedNode.speed = \"125\"
$AddedNode.mac = \"AA-BB-CC\"
$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
une solution, en trichant un peu
[code:1]
#D'après www.vistax64.com/powershell/28838-creati...sing-powershell.html
$xmlfile=\"c:\temp\data.xml\"
[XML]$Data=GC $xmlfile
$Node=switch (@($Data.discover.switch.interfaces.GetEnumerator()).count)
{
0 {Throw \"Impossible de créer un noeud dont le contenu est inconnu\"}
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 = \"1\"
$AddedNode.speed = \"125\"
$AddedNode.mac = \"AA-BB-CC\"
$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
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Arnaud
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 6
- Remerciements reçus 0
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 \"résolu\" si tel était le cas ..
Concernant l'ajout d'XSD, je préfère éviter d'ajouter \"bcp\" de chose, et surtout des DDL, le fichier XML n'est la que pour avoir un accès au donné sous forme de \"data\".
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
).
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
Concernant l'ajout d'XSD, je préfère éviter d'ajouter \"bcp\" de chose, et surtout des DDL, le fichier XML n'est la que pour avoir un accès au donné sous forme de \"data\".
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
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.
- Arnaud
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 6
- Remerciements reçus 0
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 \"Add-node\" et \"Add-interface\", voici ce que j'ai essayé de faire : (Note, j'ai essayé de \"traduire\" la fonction add-interface qui fonctionne (merci d'ailleurs), pour \"add-node\", 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 = \"
<discover version='1.0'>
<switch>
<name>0</name>
<address>0</address>
<version>0</version>
<interfaces>
<interface>
<desc>0</desc>
<type>0</type>
<speed>0</speed>
<mac>0</mac>
<adminstatus>0</adminstatus>
<operstatus>0</operstatus>
</interface>
</interfaces>
</switch>
</discover>\"
$template | Out-File $filename
}
Create-template $xmlfile
####################
#[xml]$Config = Get-Content $xmlfile
#$element = $Config.CreateElement(\"interface\"«»)
#$element.setattribute(\"desc\", \"1er\"«»)
#$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 \"Impossible de créer un noeud dont le contenu est inconnu\"}
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 \"AppendChild\" 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 \"name\" \"address\" \"version\"
add-interface $xmlfile 1 1 1 1 1 1
add-interface $xmlfile 12 12 12 12 12 12
add-node $xmlfile \"name2\" \"address2\" \"version2\"
add-interface $xmlfile 13 13 13 13 13 13
[/code:1]
Une idée de pourquoi ?
Mon template doit obligatoirement comporter des valeurs vide ?
L'idée final étant de pouvoir avoir une fonction \"Add-node\" et \"Add-interface\", voici ce que j'ai essayé de faire : (Note, j'ai essayé de \"traduire\" la fonction add-interface qui fonctionne (merci d'ailleurs), pour \"add-node\", 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 = \"
<discover version='1.0'>
<switch>
<name>0</name>
<address>0</address>
<version>0</version>
<interfaces>
<interface>
<desc>0</desc>
<type>0</type>
<speed>0</speed>
<mac>0</mac>
<adminstatus>0</adminstatus>
<operstatus>0</operstatus>
</interface>
</interfaces>
</switch>
</discover>\"
$template | Out-File $filename
}
Create-template $xmlfile
####################
#[xml]$Config = Get-Content $xmlfile
#$element = $Config.CreateElement(\"interface\"«»)
#$element.setattribute(\"desc\", \"1er\"«»)
#$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 \"Impossible de créer un noeud dont le contenu est inconnu\"}
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 \"AppendChild\" 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 \"name\" \"address\" \"version\"
add-interface $xmlfile 1 1 1 1 1 1
add-interface $xmlfile 12 12 12 12 12 12
add-node $xmlfile \"name2\" \"address2\" \"version2\"
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.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 14 ans 9 mois #9731
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:multiple sous-noeud fichier XML
DragoonMaster écrit:
Tu clones un objet que tu ne rattaches à rien, donc tu ne fais rien, cqfd.
DragoonMaster écrit:
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=\"Global value\"
Function Test($type) {
New-XDocument Types -Encoding \"UTF-16\" {
Type {Name {\"$Type\"} }
}|
Foreach { $_.Declaration.ToString(); $_.ToString()
}
}
Test \"Parameter value\"
# result = Global Value
<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>
<Types>
<Type>
<Name>Global value</Name>
</Type>
</Types>
[/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
Non c'est l'usage que tu en fais qui ne marche pas.J'arrive bien à créer mes sous-noeud, mais c'est désormais le Clone() qui ne marche plus correctement (voir du tout !).
Tu clones un objet que tu ne rattaches à rien, donc tu ne fais rien, cqfd.
DragoonMaster écrit:
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.Concernant l'ajout d'XSD, je préfère éviter d'ajouter \"bcp\" de chose
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=\"Global value\"
Function Test($type) {
New-XDocument Types -Encoding \"UTF-16\" {
Type {Name {\"$Type\"} }
}|
Foreach { $_.Declaration.ToString(); $_.ToString()
}
}
Test \"Parameter value\"
# result = Global Value
<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\"?>
<Types>
<Type>
<Name>Global value</Name>
</Type>
</Types>
[/code:1]
Comme quoi les modules Powershell c'est bien, mais pas pour tout
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Arnaud
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
Réduire
Plus d'informations
- Messages : 6
- Remerciements reçus 0
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 \"instance\" 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 \"Impossible de créer un noeud dont le contenu est inconnu\"}
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 \"AppendChild\" 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 \"name\" \"address\" \"version\"
add-interface $xmlfile 1 1 1 1 1 1
add-interface $xmlfile 12 12 12 12 12 12
add-node $xmlfile \"name2\" \"address2\" \"version2\"
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 à \"name2, address2 et version2\".
Soit un renommage du premier noeud.
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 \"Impossible de créer un noeud dont le contenu est inconnu\"}
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 \"AppendChild\" 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 \"name\" \"address\" \"version\"
add-interface $xmlfile 1 1 1 1 1 1
add-interface $xmlfile 12 12 12 12 12 12
add-node $xmlfile \"name2\" \"address2\" \"version2\"
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 à \"name2, address2 et version2\".
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
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- [RESOLU] multiple sous-noeud fichier XML