cs_JMO
Messages postés1854Date d'inscriptionjeudi 23 mai 2002StatutMembreDernière intervention24 juin 2018
-
Modifié par cs_JMO le 27/11/2015 à 22:57
Whismeril
Messages postés18610Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention25 septembre 2023
-
29 nov. 2015 à 16:57
Via une fonction, je souhaite récupéré la valeur du champ "contrat" d'un client (customer name) et d'un alias (alias name) passés en paramètre.
Mon code ci-dessous me retourne le bon résultat (contrat=5464),
mais je suppose qu'il y a plus adroit pour y arriver.
Using reader As New IO.StreamReader(pathroot & pathconfig & "TestConfig_forum.xml")
xdoc = XDocument.Load(reader)
End Using
Dim var1 As String = "CLIENT1"
Dim var2 As String = "SV_CLIENT1"
Dim var3 As String = "contrat"
Dim test = From items In xdoc.Descendants("Customer").Elements("Alias").Attributes(var3) _
Where CStr(items.Parent.Parent.Attribute("name").Value) = var1 And _
CStr(items.Parent.Attribute("name").Value) = var2
Select items
MessageBox.Show(test.First.ToString)
Merci de vos suggestions.
A voir également:
Linq extraction fichier XML - récupération champ précis
Whismeril
Messages postés18610Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention25 septembre 2023629 27 nov. 2015 à 23:04
Bonsoir,
Value est de type string donc tu n'as pas besoin de faire la conversion avec CStr.
Si tu es sûr de n'avoir qu'une occurrence, tu peux utiliser la clause Single au lieu de Where.
Sinon c'est une bonne solution.
Tu peux aussi enchainer 2 requête, la première sélectionne le client, la seconde l'alias.
cs_JMO
Messages postés1854Date d'inscriptionjeudi 23 mai 2002StatutMembreDernière intervention24 juin 201827 27 nov. 2015 à 23:15
Bonsoir Whismeril,
Merci de cette réponse aussi rapide.
Je modifie mon script pour enlever le Cstr superfux et me dirige sur MSDN pour explorer la clause Single que tu me suggères d'employer.
Pour l'occurrence, oui, il y en a une seule, le xml que j'ai créé me sers comme un fichier ini.
J'hésite à lire avec une fonction 1000 fois le fichier d'une centaine de lignes ou de mettre mes données du xml dans un dictionnaire.
Bonne soirée.
Whismeril
Messages postés18610Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention25 septembre 2023629 28 nov. 2015 à 00:22
Sans hésitation, charge le dans une collection (liste, dictionnaire) et fais tes requêtes directement sur cette collection, ça va beaucoup plus vite.
cs_JMO
Messages postés1854Date d'inscriptionjeudi 23 mai 2002StatutMembreDernière intervention24 juin 201827
>
Whismeril
Messages postés18610Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention25 septembre 2023 28 nov. 2015 à 12:06
Bonjour Whismeril,
Merci de tes conseils.
J'ai utilisé un dictionnaire.
' Parcours du fichier XML Using reader As New IO.StreamReader(pathroot & pathconfig & fileconfig) xdoc = XDocument.Load(reader) End Using
Dim job = From items In xdoc.Descendants("Customer") _ Select items
For Each items As XElement In job Dim customer As String = items.@name Dim aliascustomer = From itemsalias In items.Descendants("Alias").OrderBy(Function(p) p.Attribute("name").Value) Select itemsalias
For Each itemscustomer In aliascustomer Dim parameters = (From itemsparameter In itemscustomer.Descendants("Parameter") Select itemsparameter.Value).ToList()
dicoCustomer.Add(customer & New String("|"c, 1) & itemscustomer.@name, _ items.@product & New String("|"c, 1) & _ items.@axone & New String("|"c, 1) & _ items.@infocgn & New String("|"c, 1) & _ items.@env & New String("|"c, 1) & _ items.@app & New String("|"c, 1) & _ items.@job & New String("|"c, 1) & _ itemscustomer.@contrat & New String("|"c, 1) & _ itemscustomer.@codebien & New String("|"c, 1) & _ String.Join(New String("|"c, 1), parameters)) Next Next
Private Function returnTicketing(ByVal keyword As String, ByVal choice As String) As String If dicoCustomer.ContainsKey(keyword) Then Select Case choice Case "Contract" : Return dicoCustomer.Item(keyword).ToString.Split(New Char() {Convert.ToChar(124)}, StringSplitOptions.None)(6) Case "Category" : Return dicoCustomer.Item(keyword).ToString.Split(New Char() {Convert.ToChar(124)}, StringSplitOptions.None)(7) End Select End If Return String.Empty End Function
Whismeril
Messages postés18610Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention25 septembre 2023629 29 nov. 2015 à 14:34
Je pense que tu te complique la vie avec un dictionnaire, son utilité est de lier 2 valeurs, pas 50 compilées.
Il me semble plus judicieux de charger le fichier xml dans une liste d'une classe adaptée et de faire une requête sur cette liste pour alimenter l'autre.
Whismeril
Messages postés18610Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention25 septembre 2023629 29 nov. 2015 à 15:44
Par exemple, en répondant à ta 1er question, trouver le numéro du contrat en fonction du nom du client et de l'alias
La classe d'abord
Public Class AliasJMO
Public Property Contrat() As Integer
Public Property Nom() As String
Public Property CodeBien() As String
Public Property Parametres() As List(Of String)
End Class
Public Class Client
Public Property Nom() As String
Public Property Aliass() As List(Of AliasJMO)
Public Shared Function ChargeXML(ByVal Path As String) As List(Of Client)
Dim xdoc As XDocument = XDocument.Load(Path)
Return (
From c In xdoc.Descendants("Customer")
Select New Client With {.Nom = c.Attribute("name").Value, .Aliass = (
From a In c.Descendants("Alias")
Select New AliasJMO With {.Nom = a.Attribute("name").Value, .Contrat = Convert.ToInt32(a.Attribute("contrat").Value), .CodeBien = a.Attribute("codebien").Value, .Parametres = (
From p In a.Descendants("Parameter")
Select p.Value).ToList()}).ToList()}).ToList()
End Function
End Class
Ensuite la ligne qui demande le chargement
Dim clients As List(Of Client) = Client.ChargeXML("JMO.xml")
'plus loin la recherche du numéro de contrat
Dim monContrat As Integer = clients.Single(Function(c) c.Nom = "CLIENT1").Aliass.Single(Function(a) a.Nom = "SV_CLIENT1").Contrat
Pas de split "tordu", on cherche directement la propriété qui va bien.
Pour la requête j'ai considéré que chaque client est unique et qu'un alias est unique par client, sinon on peut combiner Where et First.
cs_JMO
Messages postés1854Date d'inscriptionjeudi 23 mai 2002StatutMembreDernière intervention24 juin 201827 29 nov. 2015 à 15:55
Bonjour Whismeril,
Merci de tes propositions.
En effet, mes split sur les keys et les values du dico ne sont pas très élégants !!!
jean-marc
Whismeril
Messages postés18610Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention25 septembre 2023629
>
cs_JMO
Messages postés1854Date d'inscriptionjeudi 23 mai 2002StatutMembreDernière intervention24 juin 2018 Modifié par Whismeril le 29/11/2015 à 16:57
Ce n'est pas une question d'élégance, mais d'efficacité
sérialiser un string pour le spliter juste après, en temps d'exécution ça doit pas être le mieux (quoique parfois c'est surprenant)
pas de construction de string pour la recherche, on associe une propriété à une valeur
dans 6 mois quand tu reviendras modifier une recherche, tu vas perdre du temps à te demander ou se trouve ton info dans le string sérialité, alors qu'une propriété bien nommé parle de soit
27 nov. 2015 à 23:15
Merci de cette réponse aussi rapide.
Je modifie mon script pour enlever le Cstr superfux et me dirige sur MSDN pour explorer la clause Single que tu me suggères d'employer.
Pour l'occurrence, oui, il y en a une seule, le xml que j'ai créé me sers comme un fichier ini.
J'hésite à lire avec une fonction 1000 fois le fichier d'une centaine de lignes ou de mettre mes données du xml dans un dictionnaire.
Bonne soirée.
28 nov. 2015 à 00:22
28 nov. 2015 à 12:06
Merci de tes conseils.
J'ai utilisé un dictionnaire.
Et pour charger ma ListOf
Bonne journée