2013-08-12 2 views
0

je l'XDocument suivante:Travailler avec XDocument

<?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:"> 
    <D:response> 
     <D:href>http://aaa</D:href> 
     <D:propstat> 
      <D:prop> 
       <D:displayname>a</D:displayname> 
       <D:isFolder>t</D:isFolder> 
      </D:prop> 
      <D:status>HTTP/1.1 200 OK</D:status> 
     </D:propstat> 
    </D:response> 
    <D:response> 
     . 
     . 
    </D:response> 

Comment puis-je obtenir toutes les réponses? (Tout sous "D: réponse" tag, et évidemment tout sous "D: propstat" et "D: prop" tags - Je veux obtenir D: href, D: displayname, D: isFolder)

Je suis Pour ce faire:

XNamespace d = "DAV:"; 
foreach (var file in doc.Descendants(d + "response")) 
{ 
    if ((string)file.Element(d + "href") != (string)Configuration.Configs["baseUrl"]) 
    { 
     string ref = (string)file.Element(d + "href"); 
     foreach (var propstat in file.Descendants(d + "propstat")) 
      foreach (var prop in propstat.Descendants(d + "prop")) 
      { 
       string name = (string)prop.Element(d + "displayname"); 
       if (prop.Element(d + "isFolder") != null && (string)prop.Element(d + "isFolder") == "t") 
        string type = "folder"; 
       else 
        string type = "file"; 
      } 
    } 
} 

Y a-t-il un meilleur moyen?

+0

Le 'D:' est un préfixe qui définit l'espace de noms. Vous devez rechercher des éléments dans cet espace de noms; vous ne pouvez pas utiliser l'espace de noms par défaut. – Yuck

+0

Est-il possible que la réponse ait plusieurs éléments 'propstat'? Ou que propstat aura plusieurs éléments 'prop' ou' status'? Aussi quels éléments pourraient manquer dans votre xml? –

Répondre

0

Vous pouvez le faire. Il est un peu maladroit, mais fonctionne

var result = doc.Descendants(d + "response") 
       .Select(x => new { href = x.Element(d + "href"), nodes = x.Descendants(d + "prop") }) 
       .Select(y => new 
    { 
     href = (string)y.href.Value, 
     displayname = (string)y.nodes.Select(z => z.Element(d + "displayname")).First().Value, 
     isFolder = (string)y.nodes.Select(z => z.Element(d + "isFolder")).First().Value 
    }).ToList(); 
0

Dans vous scénario je serais recommande fortement l'utilisation de XPath

\\D:response obtient tous D: éléments de réponse dans le document

\\D:response\D:href tous les éléments href

\\D:response\D:propstat\D:prop\D:displayname tous les éléments displayName

\\D:response\D:propstat\D:prop\D:isFolder tous les éléments isFolder

si vous avez besoin d'un chemin relatif il suffit de déposer le \\. S'il vous plaît, en savoir plus sur XPath dans le lien que j'ai fourni. Cela vaudra certainement votre investissement.

0

Vous pouvez introduire de nouvelles variables de gamme pour simplement votre demande:

XNamespace d = "DAV:"; 
var responses = from r in xdoc.Descendants(d + "response") 
       let propstat = r.Element(d + "propstat") 
       let prop = propstat.Element(d + "prop") 
       let isFolder = (string)prop.Element(d + "isFolder") 
       select new 
       { 
        Href = (string)r.Element(d + "href"), 
        Status = (string)propstat.Element(d + "status"), 
        Name = (string)prop.Element(d + "displayname"), 
        Type = (isFolder == null || isFolder == "t") ? 
          "folder" : "file" 
       }; 

NOTE: Cette réponse suppose que votre réponse aura un élément propstat avec un élément prop à l'intérieur.

0

Vous pouvez essayer ceci:

using System; 
using System.IO; 
using System.Linq; 
using System.Xml.Linq; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var xml = File.ReadAllText("input.xml"); 
     var ns = "DAV:"; 
     var doc = XDocument.Parse(xml); 
     doc.Descendants(XName.Get("displayname", ns)) 
      .ToList().ForEach(dn => 
     { 
      var isFolder = ((XElement)dn.NextNode).Value; 
      var href = ((XElement)dn.Parent.Parent.PreviousNode).Value; 
      Console.WriteLine("{0} {1} {2}", href, dn.Value, isFolder); 
     }); 
    } 
} 

Ou comme ceci:

doc.Descendants(XName.Get("response", ns)) 
    .ToList().ForEach(r => 
{ 
    var href = r.Descendants(XName.Get("href", ns)) 
     .First().Value; 
    r.Descendants(XName.Get("displayname", ns)) 
     .ToList().ForEach(dn => { 
     var isFolder = ((XElement)dn.NextNode).Value; 
     Console.WriteLine("{0} {1} {2}", href, dn.Value, isFolder); 
    }); 
});