IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Compter un nombre de noeud "toto" XML


Sujet :

C#

  1. #21
    Expert éminent
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Points : 7 660
    Points
    7 660
    Par défaut
    Pour la différence de taille c'est normal car je n'ai pas précisé d'options de formatage pour l'écriture. Par défaut pour l'indentation ce sont des espaces qui sont utilisés, cela prend donc plus de place par rapport à l'utilisation de tabulation.

    Pour commenter le code alors cette partie charge le document et ajoute un attribut ViewCount sur chaque élément viewstruct. La valeur de cet attribut est le nombre de descendants view de l'élément viewstruct.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(@"d:\configuration.xml");
     
    XmlNamespaceManager mgr = new XmlNamespaceManager(xmlDoc.NameTable);
    mgr.AddNamespace("x", "http://www.generix.fr/technicalframework/configuration");
     
    foreach (XmlNode node in xmlDoc.SelectNodes("//x:viewstruct", mgr))
    {
        XmlAttribute att = xmlDoc.CreateAttribute("ViewCount");
        att.Value = node.CreateNavigator().Evaluate("count(.//x:view)", mgr).ToString();
        node.Attributes.Append(att);
    }
    Ensuite on crée une copie du document original dont on retire tous les élément viewstruct.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    XmlDocument xmlDocCopy = new XmlDocument();
    xmlDocCopy.LoadXml(xmlDoc.OuterXml);
    xmlDocCopy.SelectSingleNode("//x:viewstruct_def", mgr).RemoveAll();
    Après on crée une XPathExpression qui sera utilisée pour trier les éléments viewstruct en se basant sur la valeur de l'attribut ViewCount. Le tri est configuré de manière décroissante. On récupère enfin un itérateur sur les éléments pour les parcourir dans l'ordre du tri.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    XPathNavigator navigator = xmlDoc.CreateNavigator();
     XPathExpression selectExpression = navigator.Compile("//x:viewstruct_def/x:viewstruct");
    selectExpression.AddSort("@ViewCount", XmlSortOrder.Descending, XmlCaseOrder.None, "", XmlDataType.Number);
    selectExpression.SetContext(mgr);
     
    XPathNodeIterator nodeIterator = navigator.Select(selectExpression);
    Pour finir, on parcours chaque élément et on l'ajoute à la copie (en retirant l'attribut ViewCount au passage) et on sauvegarde le document XML ainsi généré.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (nodeIterator.MoveNext())
    {
        XmlNode importedLinkNode = xmlDocCopy.ImportNode((XmlNode)nodeIterator.Current.UnderlyingObject, true);
        importedLinkNode.Attributes.RemoveNamedItem("ViewCount");
        xmlDocCopy.SelectSingleNode("//x:viewstruct_def", mgr).AppendChild(importedLinkNode);
    }
     
    xmlDocCopy.Save(@"d:\Output.xml");
    En utilisant XSLT le traitement est plus rapide et moins gourmand en mémoire (ratio de 4 environ, 2.5 secondes contre 600ms et 124Mo contre 28Mo). Seul hic, la présence de l'espace de noms par défaut (xmlns) me pose problème. A priori avec XSLT 2.0 on pourrait y arriver mais .Net ne gère que XSLT 1.0. Dommage car le code est beaucoup plus simple et plus performant ^^

  2. #22
    Expert éminent
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Points : 7 660
    Points
    7 660
    Par défaut
    Petit complément, à force de lecture j'ai enfin compris le problème côté XSL et j'ai donc réussi à me dépatouiller avec tout ça. Au final c'est beaucoup plus "simple".

    Côté code
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // Utilisation d'un XPathDocument pour le traitement (moins lourd qu'un XmlDocument)
    XPathDocument xpathDoc = new XPathDocument(@"d:\configuration.xml");
     
    // Paramétrage pour l'écriture : indentation avec tabulation comme caractère d'indentation
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    settings.IndentChars = "\t";
     
    // XmlReader sur le XSL. Pour l'exemple le fichier XSL se trouve 
    // dans les ressources de l'application (Properties.Resources...)
    using (XmlReader reader = XmlReader.Create(new StringReader(Properties.Resources.SortXml)))
    // XmlWriter pour créer le fichier de sortie
    using (XmlWriter writer = XmlWriter.Create(@"d:\output.xml", settings))
    {
        // Chargement du XSL.
        XslCompiledTransform sortXsl = new XslCompiledTransform();
        sortXsl.Load(reader);
        // Application du XSL afin de générer le nouveau fichier.
        sortXsl.Transform(xpathDoc, writer);
    }
    Tout le reste est dans la feuille de style XSL utilisée
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:x="http://www.generix.fr/technicalframework/configuration">
     
      <!-- Template pour le noeud viewstruct_def -->
      <xsl:template match="x:viewstruct_def">
        <!-- Création "explicite" de l'élément pour éviter l'ajout du namespace xmlns="" -->
        <xsl:element name="{name()}" namespace="http://www.generix.fr/technicalframework/configuration">
          <!-- Tri des viewstruct -->
          <xsl:apply-templates select="x:viewstruct">
            <xsl:sort select="count(.//x:view)" data-type="number" order="descending"/>
          </xsl:apply-templates>
        </xsl:element>
      </xsl:template>
     
      <!-- Template pour la recopie des éléments viewstruct -->
      <xsl:template match="x:viewstruct">
        <xsl:copy-of select="."/>
      </xsl:template>
     
      <!-- Template identité pour la recopie des autres éléments -->
      <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:template>
     
    </xsl:stylesheet>
    En espérant que ça réponde à ton besoin ^^

  3. #23
    Membre régulier Avatar de Klivor
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    143
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 143
    Points : 100
    Points
    100
    Par défaut
    MERCI
    Problème résolu.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. compter le nombre de balise d'un fichier xml
    Par nancy maman dans le forum Général Python
    Réponses: 17
    Dernier message: 12/08/2011, 16h41
  2. compter nombre de noeud dans un XML
    Par geek21 dans le forum Flex
    Réponses: 36
    Dernier message: 14/08/2009, 15h46
  3. [XPATH] compter le nombre de noeuds différents
    Par John95 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 21/11/2008, 09h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo