Acces aux valeurs dans un xml [Résolu]

Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
- - Dernière réponse : Whismeril
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
- 17 mai 2019 à 20:21
Bonjour,

Je suis sous vb.net et je cherche a extraire des valeurs d'un fichier xml. J'arrive à récupérer 2 des 3 valeurs que j'ai besoin.
Le xml est de cette forme:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="styles/fixture+layer+layers@html@default.xsl"?>
<?xml-stylesheet type="text/xsl" href="styles/fixture+layer+layers@csv.xsl" alternate="yes"?>
<MA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.malighting.de/grandma2/xml/MA" xsi:schemaLocation="http://schemas.malighting.de/grandma2/xml/MA http://schemas.malighting.de/grandma2/xml/3.6.1/MA.xsd" major_vers="3" minor_vers="6" stream_vers="1">
<Info datetime="2019-04-01T09:20:42" showfile="macbeth-test" />
<Layers index="3">
<Layer index="1" name="gradateurs">
<Fixture index="0" name="Dim 68" fixture_id="68" channel_id="68">
<FixtureType name="2 Dimmer 00">
<No>2</No>
</FixtureType>
<SubFixture index="0" react_to_grandmaster="true" color="ffffff">
<Patch>
<Address>143</Address>
</Patch>
<AbsolutePosition>
<Location x="0" y="0" z="0" />
<Rotation x="0" y="-0" z="0" />
<Scaling x="1" y="1" z="1" />
</AbsolutePosition>
<Channel index="0" />
</SubFixture>
</Fixture>


Voila ce que j'ai codé:


Dim cpo_patch As XDocument = XDocument.Load(Lbl_patch.Text)
Dim popatch As XElement = cpo_patch.Root.<Layers>.FirstOrDefault
Dim listPatch As IEnumerable(Of XElement) = popatch.Elements()

For Each listfixture In listPatch

If listfixture.HasElements Then

Dim Fixtures As IEnumerable(Of XElement) = listfixture.Elements

Dim u As Integer = 0

For Each fixture In Fixtures

If fixture.HasElements Then

Tbl_Patch(u, 0) = fixture.@<channel_id>
Tbl_Patch(u, 1) = fixture.<fixturetype>.@<name>
Tbl_Patch(u, 2) = fixture.@<name>

MsgBox(Tbl_Patch(u, 0) & " / " & Tbl_Patch(u, 1) & " / " & Tbl_Patch(u, 2))

End If
Next

End If

Next


ce qui marche pas c'est fixture.<FixtureType>.@<name>

Avez vous des idées sur ce qui ne va pas ?
Afficher la suite 

Votre réponse

20/88 réponses

Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
J'ai tapé de tête sur ma tablette....
Commenter la réponse de Whismeril
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
0
Merci
Bonjour,
Oui c'est moins facile sur tablette ou sur smartphone. En plus il y a des corrections automatiques qui sont parfois énervantes et les claviers sont plus petits.

je suis en train de vouloir afficher les données de mesFixturesGroupees dans le datagridview1, mais je n'y arrive pas, alors que ça fonctionnait avant le groupage. Quelles sont les différences ?.
P.S. je souhaite afficher seulement les .NomType regroupés.
Commenter la réponse de wholehog2
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
Bonsoir

là encore cela te crée une arborescence, il y a "les clés", les valeurs par lesquelles c'est regroupé, et sous chaque clé les fixtures associées.

On peut créer une collection ou chaque item aura la clé et le nomtype, mais tu verras n fois la même clé.
On peut aussi utiliser un treeview ou 2 ListBix (pas forcément besoin de datagridview puisque tu ne veux voir qu'une valeur).

Dis moi ce qui te conviendrait le mieux
Commenter la réponse de Whismeril
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
0
Merci
Je préférerais l'afficher dans un datagridview, puis quand je clique sur une ligne du datagridview ça m'affiche la liste des fixtures dans un deuxième datagridview.
C'est ce que j'avais réussi à faire.
Commenter la réponse de wholehog2
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
Ok, mais je tiens compte de ça
P.S. je souhaite afficher seulement les .NomType regroupés.

Ça va te faire 2 datagridview d'une colonne.
Ça me paraitrait plus logique d'afficher la fixture entière comme ceci
    Private mesFixturesGroupees As List(Of IGrouping(Of String, Fixture))
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim lignes As List(Of String) = File.ReadAllLines("PATCH.xml").ToList() 'on met toutes les lignes du fichier dans une lite
        lignes.RemoveAt(1) 'on enlève la ligne 1 (qui est la 2eme ligne)
        lignes.RemoveAt(1) 'on enlève la ligne 1 (qui est la 2eme ligne actuelle, soit la 3ème ancienne ligne)
        lignes(1) = "<MA>" 'on modifie la ligne 1 (qui est la 4eme ligne d'origine)

        Dim texteCorrige As String = String.Join(Environment.NewLine, lignes) 'on refait un texte complet

        Dim xDoc As XDocument = XDocument.Parse(texteCorrige) 'on parse le texte corrigé

        mesFixturesGroupees =
            (
                    From f In xDoc.Descendants("Fixture")
                    Select New Fixture With
                     {
                        .Nom = f.Attribute("name")?.Value,
                        .Numero = f.Attribute("fixture_id").Value.ToInt(),
                        .NomType = f.Element("FixtureType")?.Attribute("name")?.Value
                     }
             ).GroupBy(Function(x) x.NomType).ToList()

        DataGridView1.DataSource = mesFixturesGroupees


et dans le SelectionChanged de datagridview1
    Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) Handles DataGridView1.SelectionChanged

        Dim groupe As IGrouping(Of String, Fixture) = mesFixturesGroupees(DataGridView1.SelectedCells(0).RowIndex)


        DataGridView2.DataSource = groupe.ToList()
    End Sub

Whismeril
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274 -
Mais si tu veux juste NomType alors
    Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) Handles DataGridView1.SelectionChanged

        Dim groupe As IGrouping(Of String, Fixture) = mesFixturesGroupees(DataGridView1.SelectedCells(0).RowIndex)


        DataGridView2.DataSource = groupe.Select(Function(x) x.NomType).ToList()
    End Sub
Commenter la réponse de Whismeril
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
0
Merci
Bonjour,
Il y a une erreur quand je clique sur le dtagridview1 à la ligne :
Dim groupe As IGrouping(Of String, Fixture) = mesFixturesGroupees(DataGridView1.SelectedCells(0).RowIndex)

L'erreur est : System.NullReferenceException : 'Variable objet ou variable d'un bloc With non définie."
Cette erreur est présente pour les 2 propositions.
wholehog2
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
-
En faisant des recherches, il se trouve que c'est la portée de la variable mesFixturesGroupees qui n'est pas bonne. J'ai mis les datagridview sur une autre form je pense que le souci vient de là.
wholehog2
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
-
J'ai solutionné en déclarant une variable global en mettant mesFixturesGroupees dedans, car je n'arrivais pas à déclarer mesFixturesGroupees en public en tant que list. As tu une autre solution ?
Commenter la réponse de wholehog2
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
Ha oui, il faut que tu passes la collection à ton autre formulaire.
Quelques façons de faire
https://codes-sources.commentcamarche.net/faq/11107-interactions-entre-form-en-net-c-et-vb-net
Commenter la réponse de Whismeril
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
Oui, voir mon message précédent.
Les variables globales, c’est pas conseillé.
Commenter la réponse de Whismeril
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
0
Merci
J'ai encore un souci !
Je n'arrive pas à trier mon datagridview2 par rapport à la première colonne, qui est le numéro.
j'ai écrit ceci:
 DataGridView2.Sort(DataGridView2.Columns(0), System.ComponentModel.ListSortDirection.Ascending)

j'ai l'erreur:
System.InvalidOperationException : 'Pour être trié, un contrôle DataGridView doit être lié à l'objet IBindingList.
Sauf que moi le datagridview est lié à une liste. Peut être que la liste doit être triée avant de l'afficher dans le datagridview ?
Comment puis je faire ?
Commenter la réponse de wholehog2
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
Oui, une liste n'est par un IBindingList, le plus simple en effet est de trier avant avec un OrderBy

DataGridView2.DataSource = groupe.OrderBy(Function(x) x.Numero).ToList()


Tu devrais faire un tour là https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
Il y a 101 exemples d'utilisation de Linq, en C#, mais avec https://www.qwant.com/?q=c%23+to+vb&t=web ça sera en VB

Commenter la réponse de Whismeril
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
0
Merci
Un petit message pour te dire que je n'ai pas abandonné, mais je n'ai pas beaucoup de temps à consacrer au développement en ce moment.
J'ai réussi à importer toutes les données dont j'avais besoin, maintenant reste la phase d'écriture du fichier.
Effectivement je suis conscient que j'ai plein de choses à apprendre et j'apprécie d'autant plus ton aide.
A bientôt.
Commenter la réponse de wholehog2
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
0
Merci
Bonjour(soir)
De retour pour un problème.
J'ai un numéro de fixture pour lequel je veux récupérer son fixturetype ( dans la liste MesFixtures c.f. post 11) qui me permettra de récupérer ensuite des valeurs dans une autre liste.
Mais j'ai une erreur :


Comment dois-je déclarer MesFixtures car apparemment c'est ce qui ne va pas ?
Merci.
Commenter la réponse de wholehog2
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
Bonsoir,

je rentre de quelques jours d'absence.
Il faut que je me replonge dans ton projet.
Commenter la réponse de Whismeril
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
Bonsoir,

dans le post 11, mesFixtures est une liste.
Une liste est parfaitement connue par Linq.
Donc ce n'est pas ça le problème à mon sens.

Peux tu poster un peu plus de code?
Commenter la réponse de Whismeril
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
0
Merci
Bonsoir,
Voici un peu plus de code :
                    Dim Fixtures_groupes_2_par_cues = Fixtures_par_cues.GroupBy(Function(n) n.Num_fixture).ToList()
                    For Each group In Fixtures_groupes_2_par_cues

                        strgBuilt.Append("$$AL " & group.Key.ToString & " 0 0 0 65535 0 0")
                        strgBuilt.AppendLine()

                        For Each attr In group

                            Select Case attr.Num_cobalt
                                Case 1 '  c'est le PAN
                                    If attr.Valeur < 0 Then
                                        Dim valtemp = (From fix In mesFixtures Where fix.Numero = group.Key.ToString Select fix)
                                    Else
                                    End If
                            End Select

                            strgBuilt.Append("$$A " & group.Key & " " & attr.Num_cobalt & " " & attr.Valeur & " " & attr.Num_type_param_cobalt & " 0 0 0 0 0 0 0")
                            strgBuilt.AppendLine()
                        Next
                    Next


Je dois récupérer le nom du FixtureType en fonction du numero du fixture (dans la liste mesFixtures)sous cette forme :

pour ensuite pouvoir récupérer la valeur minimal et maximale de ce paramètre (qui ce trouve dans la liste mesFixture_type)pour pouvoir calculer un pourcentage. mesFixture_type est sous cette forme :


C'est pass evident à expliquer !
Dis moi si il y a quelque chose que tu ne comprends pas ?
Commenter la réponse de wholehog2
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
D'après le message d'erreur, il te manquerait un import en haut de ton fichier de code
https://docs.microsoft.com/fr-fr/dotnet/visual-basic/language-reference/error-messages/expression-of-type-type-is-not-queryable
wholehog2
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
-
Oui j'ai vue ça dans mes recherches. Mais apparement tout y est.
Commenter la réponse de Whismeril
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
Si tu fais click droit / Atteindre la définition sur mesFixtures, tu arrives bien à une liste?
Commenter la réponse de Whismeril
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
0
Merci
Non. J'arrive au début de la classe form1 ou j'ai déclarer mesFixtures en Public pour qu'elle soit accessible depuis toutes les sub.
Commenter la réponse de wholehog2
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274
0
Merci
Ça c’est pas le top, mais tu l’as bien déclaré comme une liste?
Commenter la réponse de Whismeril
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
0
Merci
J'ai essayé mais quand je mets :
 Public mesFixtures As List(Of Fixture)

il me dit :
wholehog2
Messages postés
58
Date d'inscription
lundi 25 juin 2007
Statut
Membre
Dernière intervention
17 mai 2019
-
Il faut donc que je la déclare dans un module ?
Whismeril
Messages postés
13316
Date d'inscription
mardi 11 mars 2003
Statut
Non membre
Dernière intervention
25 mai 2019
274 -
Non, c’est à la classe qu’il faut ajouter le modificateur Public

Public class Fixture
Commenter la réponse de wholehog2