2009-10-11 2 views
1

J'utilise XmlReader pour lire un fichier XML et je veux compter l'élément XML juste en dessous de l'élément Document, car je sais que ce devrait être l'élément racine.Qu'est-ce que XmlNodeType.Document? Différence entre XmlNodeType.Element et XmlNodeType.Document

XML

<?xml version="1.0" encoding="utf-8"?> 
<NewsLetters> 
    <EMail Date="10/10/2009">[email protected]</EMail> 
    <EMail Date="10/10/2009">[email protected]</EMail> 
    <EMail Date="10/10/2009">[email protected]</EMail> 
    <EMail Date="10/10/2009">[email protected]</EMail> 
</NewsLetters> 

C# Code:

public static string TotalMemberCount() 
{ 
    XmlTextReader reader = new XmlTextReader(HttpContext.Current.Server.MapPath("~/Newsletter/NewsLetter.xml")); 

    int totalCount = 0; 
    while (reader.Read()) 
    { 
     if (reader.NodeType == XmlNodeType.Element && reader.NodeType != XmlNodeType.Document) 
      totalCount++; 
    } 

    return totalCount.ToString(); 
} 

Normalement, je me attendais à 4 dossiers, mais il retourne 5 car il compte également l'élément racine. Que dois-je faire? En fait, je sais comment résoudre en utilisant XDocument, XElement et LINQ mais je veux résoudre de cette façon, ne me demandez pas pourquoi parce que je veux apprendre tous les moyens de résoudre de tels problèmes.

Merci d'avance.

Sincèrement ....

+0

Aucune réponse? Triste ... – Tarik

Répondre

2

La réponse que vous avez trouvée est imparfaite d'au moins cinq façons différentes.

  1. Il est certainement pas une « solution générique », puisque votre code dépend maintenant entièrement sur l'information dans le fichier XML - votre méthode ne peut compter que des éléments correctement si le document XML, il est le traitement contient l'attribut de drapeau que vous avez ajoutée.

  2. L'attribut indicateur n'est pas nécessaire. Chaque fois qu'un XmlReader commence au début du flux qu'il lit, le premier élément qu'il lit est toujours qui sera l'élément de premier niveau. Ça ne peut pas être autre chose. Au lieu d'ajouter un attribut à votre document pour identifier l'élément de niveau supérieur, vous pouvez simplement utiliser un indicateur pour savoir si vous avez déjà lu l'élément de niveau supérieur. Ou diable, vous pouvez simplement soustraire 1 du total.

  3. Et même si avait besoin de l'attribut d'indicateur, vous le faites mal. Vous utilisez MoveToFirstAttribute pour le trouver. Que faire s'il y a plus d'un attribut sur l'élément? Que faire si le premier attribut trouvé par votre code dont la valeur est True n'est pas Root? Et si l'un des éléments enfant a un attribut avec cette valeur? Si vous allez utiliser un attribut à cette fin, vous devez, au très moins, rechercher par nom.

  4. Ce code ne comptera pas tous les enfants éléments de l'élément de niveau supérieur, il comptera tous descendant éléments. Le lecteur se déplace d'un nœud à l'autre dans l'ordre des documents.Si un nœud d'élément a un nœud enfant, ce nœud enfant est le nœud suivant qui est lu par Read(). Il existe des méthodes du XmlReader que vous pouvez utiliser pour lire un élément entier et tout son contenu dans une seule gorgée, mais vous ne les utilisez pas. La condition reader.NodeType != XmlNodeType.XmlDeclaration && reader.NodeType == XmlNodeType.Element est redondante: il est impossible qu'un noeud puisse être une déclaration XML s'il s'agit d'un élément.

+0

Alors que dois-je faire? – Tarik

0

Quoi qu'il en soit, je trouve ma propre solution, ce que je cherche à atteindre est de trouver une solution générique, donc je suis venu avec une telle solution:

XML

<?xml version="1.0" encoding="utf-8"?> 
<NewsLetters Root="True"> 
    <EMail Date="10/10/2009">[email protected]</EMail> 
    <EMail Date="10/10/2009">[email protected]</EMail> 
    <EMail Date="10/10/2009">[email protected]</EMail> 
    <EMail Date="10/10/2009">[email protected]</EMail> 
</NewsLetters> 

C#

public static string TotalMemberCount() 
    { 
     int totalCount = 0; 
     using (XmlTextReader reader = new XmlTextReader(HttpContext.Current.Server.MapPath("~/Newsletter/NewsLetter.xml"))) 
     { 
      while (reader.Read()) 
      { 
       if (reader.NodeType != XmlNodeType.XmlDeclaration && reader.NodeType == XmlNodeType.Element) 
       { 
        if (reader.MoveToFirstAttribute()) 
        { 
         if (reader.Value == "True") 
          //gotcha, I don't want this,this is root element 
          continue; 
        } 
        totalCount++; 
       } 
      } 
      return totalCount.ToString(); 
     } 

    } 
Questions connexes