Partage
  • Partager sur Facebook
  • Partager sur Twitter

Lire du xml

Sujet résolu
17 septembre 2020 à 9:41:02

Bonjour dans mon programme je récupère un document xml avec propfind puis ensuite j'aimerais lire les propriétés de certain nœud du xml. J'ai réussi à lire un xml basic Exemple :

<?xml version="1.0" encoding="utf-8" ?>
<Qualifiations>

  <Qualification>
    <QualificationID>1</QualificationID>
    <displayname>acte.xml</displayname>
  </Qualification>

</Qualifiations>

Le problème est que le xml que j'ai à lire ne ressemble pas à ca ,voici un exemple :

<?xml version="1.0" encoding="utf-8" ?>

<D:multistatus xmlns:D="DAV:" xmlns:Office="urn:schemas-microsoft-com:office:office" xmlns:Repl="http://schemas.microsoft.com/repl/" xmlns:Z="urn:schemas-microsoft-com:">
  <br />
  <D:response>
    <D:href> mon lien /</D:href>
    <D:propstat>
      <D:prop>
        <D:displayname>blabla que je veux recuperer</D:displayname>


Je n'et pas mis les balises fermante mais je suppose vous aurait compris le principe. Le faite que la propriété et "D:" devant me dit que il n'arrive pas à me lire car il ne la compte pas comme une propriété. 

Voici mon code pour le 1er xml qui fonctionne bien sur :

        private void BindCheckBoxList()
        {

            DataSet ds = new DataSet();
            try
            {
                ds.ReadXml(Server.MapPath("xmlTest2.xml"));
                CheckBoxListId.DataSource = ds;
                CheckBoxListId.DataTextField = "displayname";
                CheckBoxListId.DataValueField = "QualificationID:";
                CheckBoxListId.DataBind();
                
            }
            catch (Exception ex)
            {
                LabelTest.Text = ex.Message;
            }
        }






-
Edité par HELBOYS 17 septembre 2020 à 9:42:20

  • Partager sur Facebook
  • Partager sur Twitter
17 septembre 2020 à 11:22:12

Ici "D" n'est pas un "nom" et ne fait pas partie des noms ni des éléments XML ni des attributs XML.

C'est un alias de namespace XML.

"D" est un alias pour un namespace d'URI "DAV:", comme  "Office" l'ai pour l'URI "urn:schemas-microsoft-com:office:office" ou encore "Repl" pour l'URI "http://schemas.microsoft.com/repl/" ou "Z" pour l'URL "urn:schemas-microsoft-com:"

Les "noms" d'éléments ou d'attributs sont souvent raccourcis et on doit passer par des résolutions de noms "pleinement qualifiés" pour que les routines utilisant des requêtes XPath fonctionnent.

Pour se simplifier la vie, on peut utiliser un XmlNamespaceManager lors des interrogations XPath.

https://docs.microsoft.com/fr-fr/dotnet/api/system.xml.xmlnamespacemanager?view=netcore-3.1

https://www.c-sharpcorner.com/UploadFile/manas1/read-xml-data-with-namespce-using-xmldocument/

  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
17 septembre 2020 à 11:38:57

Malgré l'explication et le faite que je suis aller voir les 2 liens je n'y comprend toujours rien pour résoudre cela.

Les doc Microsoft ne m'avance à rien .Surtout que la plus part des sites montre en mode console et moi je suis en web 

-
Edité par HELBOYS 17 septembre 2020 à 11:47:06

  • Partager sur Facebook
  • Partager sur Twitter
17 septembre 2020 à 12:40:34

Il faut comprendre :

<D:multistatus xmlns:D="DAV:" xmlns:Office="urn:schemas-microsoft-com:office:office" xmlns:Repl="http://schemas.microsoft.com/repl/" xmlns:Z="urn:schemas-microsoft-com:">
  <br />
  <D:response>

comme environ:

<{DAV:}:multistatus>
  <br />
  <{DAV:}:response>

et que c'est strictement équivalent à 

<X:multistatus xmlns:X="DAV:">
  <br />
  <X:response>

et donc qu'on ne pas chercher un "D:multistatus" mais être en mesure de chercher un élément ou un attribut avec "{DAV:}:multistatus" (ou "{DAV:}:" est une vue de l'esprit, une résolution d'un namespace.

C'est pour cela qu'il faut passer par un XmlNamespaceManager pour que vous choisissiez les alias utilisés pour l'URI "DAV:", qui peut être "DAV" par exemple :

<DAV:multistatus xmlns:DAV="DAV:">
  <br />
  <DAV:response>

Et avec l'XmlNamespaceManager spécifiant que le préfixe associé à l'URI "DAV:" est "DAV", une requête XPath "/DAV:multistatus" trouvera toujours la racine de votre document XML, qu'il soit écrit comme :

<D:multistatus xmlns:D="DAV:">
  <br />
  <D:response>

ou comme cela :

<X:multistatus xmlns:X="DAV:">
  <br />
  <X:response>



Attention à votre exemple qui est bien trop simpliste par rapport au travail à faire. Votre fichier "xmlTest2.xml" n'est pas un XML ordinaire mais le résultat de la sérialisation d'un DataSet, permettant ainsi de se désérialisé directement en DataSet.

Dans les fichiers XML arbitraires, vous devez analyser et interroger leur contenu via des objets types XPathNavigator, qui eux, gèrent finement la notion de namespace XML via un XmlNamespaceManager.

https://docs.microsoft.com/fr-fr/troubleshoot/dotnet/framework/query-xpathdocument-xpath-csharp

EDIT:

>Surtout que la plus part des sites montre en mode console et moi je suis en web

Ça change rien. Je ne connais aucune classe liée à la lecture du XML qui soit contrainte dans un contexte "IIS/Web Host".

-
Edité par bacelar 17 septembre 2020 à 12:54:00

  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
17 septembre 2020 à 14:47:22

Je comprend encore moin qu'au début avec tout ça. De plus les exemples Microsoft ne fonctionne pas  donc résultat je n'avance à rien. Me montrer lien des doc n'est pas utile.

Si je vient demander de l'aide ses que j'ai un minimum creusé le sujet avant 

j'ai essayé de refaire comme eu afin d'avoir un résultat et comprendre le fonctionnement mais sans suces

-
Edité par HELBOYS 17 septembre 2020 à 15:30:59

  • Partager sur Facebook
  • Partager sur Twitter
17 septembre 2020 à 15:06:42

>ses que j'ai un minimum creusé le sujet avant

>les exemples Microsoft fonctionne pas

Ces 2 constatations montrent que vous êtes complètement à la rue.

Les exemples de M$ fonctionnent dans domaines de validité, que vous n'arrivez pas à déterminer leur domaine de validité, c'est que vous n'êtes pas en mesure de les comprendre et qu'il vous manque des bases, ne vous en déplaise.

Si vous aviez les bases, mes messages ne seraient pas du chinois pour vous.

Donnez-nous votre code actuel et le comportement/message d'erreur qu'il exhibe et on vous donnera les pistes pour avancer (qui seront très probablement des liens dans la documentation M$, parce que cela ne rime à rien de réinventer une roue carrée).

Avez-vous au moins réussi à charger votre fichier XML dans un XmlDocument?

https://docs.microsoft.com/fr-fr/dotnet/api/system.xml.xmldocument?view=netcore-3.1

  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
17 septembre 2020 à 15:21:58

Le code na pas bougé pratiquement vue que j'ai effacé les choses qui ne fonctionné pas .C'est un projet important pour mon entreprise vue que la demande est pour une futur plate-forme pour le  ministère de l'intérieur .Je suis chargé de faire le fonctionnement de base afin de simplifier le travail du vrai dev qui finira le projet

 private void BindCheckBoxList()
        {

            DataSet ds = new DataSet();
            try
            {
                ds.ReadXml(Server.MapPath("xmlTest2.xml"));
                CheckBoxListId.DataSource = ds;
                CheckBoxListId.DataTextField = "{DAV:}:multistatus"; 
                CheckBoxListId.DataValueField = "{DAV:}:iscollection:";
                CheckBoxListId.DataBind();
                XmlDocument doc = new XmlDocument();
                doc.PreserveWhitespace = true;

            }
            catch (Exception ex)
            {
                LabelTest.Text = ex.Message;
            }
        }

J'ai essayé le reste surtout dans un autre projet en console afin de ne pas changer trop de chose. Voici l'erreur: 

-
Edité par HELBOYS 17 septembre 2020 à 15:30:18

  • Partager sur Facebook
  • Partager sur Twitter
17 septembre 2020 à 16:15:38

Je vous l'ai déjà indiqué, ce type de code n'est valable que pour des DataSet sérialisés en XML, pas pour un fichier XML "quelconque".

N'utilisez donc pas la méthode ReadXml d'un DataSet.

Utilisez la méthode Load de XmlDocument.

Une fois chargé dans un XmlDocument, vous devrez faire des requêtes XPath pour récupérer les informations qui vous sont nécessaire. Et c'est dans ces requêtes que vous devez correctement utiliser le "XmlNamespaceManager", avec la méthode SelectNode par exemple (voir l'un des documents dont le lien a déjà été donné).

Un exemple fait à l'arrache :

XmlDocument doc = new XmlDocument();    
doc.Load("MonFichierDeLaMortQuiTue.xml");    
    
// Creating namespace object    
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);    
nsmgr.AddNamespace("teteDeMort", "DAV:");    
    
// Fteching nodelist with injecting XML namespace object    
XmlNodeList xNode = doc.SelectNodes("teteDeMort:multistatus/teteDeMort:response", nsmgr);    
    
foreach (XmlNode xndNode in xNode)    
{  
    string Url = xndNode["Url"].InnerText;    
    
    string Titre = xndNode.SelectSingleNode("teteDeMort:propstat/teteDeMort:prop/teteDeMort:displayname", nsmgr).InnerText;      
     
    // faire le travail de remplissage d'un DataSet par exemple    
}   

P.S.: Le "{DAV}", c'était juste pour illustrer le mécanisme d'alias.

-
Edité par bacelar 17 septembre 2020 à 16:15:52

  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
17 septembre 2020 à 16:59:53

J'ai compris se que tu voulais m'expliquer part contre pourquoi il n'est pas d'accord avec mon string url ... .J'ai pourtant mis le bon nom de nœud en fonction de mon fichier xml.C'est sans doute tout bete désolé .En tout cas merci de prendre le temps de m'aider c'est super sympas :)

               XmlDocument doc = new XmlDocument();
                doc.Load(@"C:\Users\potierzo\Desktop\C#\test\test\bin\Debug\netcoreapp3.1\xmlTest2.xml");

                // Creating namespace object   
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("test", "DAV:");

                // Fteching nodelist with injecting XML namespace object   
                XmlNodeList xNode = doc.SelectNodes("test:multistatus/test:response", nsmgr);

                foreach (XmlNode xndNode in xNode)
                {
                    string Url = xndNode["href"].InnerText;

                    string Titre = xndNode.SelectSingleNode("test:propstat/displayname:prop/test:displayname", nsmgr).InnerText;

                  
                }



-
Edité par HELBOYS 17 septembre 2020 à 17:00:11

  • Partager sur Facebook
  • Partager sur Twitter
17 septembre 2020 à 18:30:10

Si le problème est en ligne 13, c'est que tout ce qui est avant fonctionne ? Même le XPath ligne 9 ?

Si c'est le cas, c'est peut-être un problème de formatage du fichier.

Pour vérifier le formatage d'un fichier XML ou la validité d'une expression XPath, il y a plein d'outils de validation, dont certain en ligne.

https://www.freeformatter.com/xpath-tester.html

  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
18 septembre 2020 à 8:36:10

Oui tout le reste fonctionne .Le xml est forcement bon il vient de ma requête propfind dans la logique. Je suis aller sur le site et il me mette "Impossible d'effectuer l'opération XPath. Expression XPath vide " 

L'erreur mise avec le code au dessus au passage est : "La référence d'objet n'est pas définie à une instance d'un objet."

-
Edité par HELBOYS 18 septembre 2020 à 9:17:51

  • Partager sur Facebook
  • Partager sur Twitter
18 septembre 2020 à 11:21:56

>"Impossible d'effectuer l'opération XPath. Expression XPath vide "

Si vous ne remplissez pas le champ de saisie pour l’expression XPath, c'est normal. :-°

Le code que j'ai fournis une adaptation à l'arrache d'un exemple d'un article donné en lien.

C'est un exemple, donc avec pas mal de raccourci en terme de gestion des erreurs.

Je ne suis pas trop usage de la propriété sans nom "[]" mais plus des Select***.

Si l'on croit la doc :

https://docs.microsoft.com/fr-fr/dotnet/api/system.xml.xmlnode.item?view=netcore-3.1#System_Xml_XmlNode_Item_System_String_

Et comme href est dans un namespace, il faut aussi utiliser le second paramètre pour spécifier le namespace.

Mais je ne sais pas si les raccourcis configurer via le XmlNamespaceManager sont valide au niveau du XmlNode, donc c'est :

string Url = xndNode["href","test"].InnerText;

soit

string Url = xndNode["href","DAV:"].InnerText;




  • Partager sur Facebook
  • Partager sur Twitter
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
18 septembre 2020 à 11:43:36

string Url = xndNode["href","DAV:"].InnerText;

La solution est bien bonne le reste du code aussi ! 

Il m'affiche bien les choses que je veux reste à faire un petit trie pour vraiment n'avoir que les fichiers 

Merci beaucoup de votre aide ;)

  • Partager sur Facebook
  • Partager sur Twitter