【问题标题】:Working with XDocument使用 XDocument
【发布时间】:2013-08-12 12:07:45
【问题描述】:

我有以下 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>  

如何获得所有回复? (“D:response”标签下的所有内容,显然“D:propstat”和“D:prop”标签下的所有内容 - 我想获得D:href,D:displayname,D:isFolder)

我正在这样做:

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";
            }
    }
} 

有没有更好的办法?

【问题讨论】:

  • D: 是定义命名空间的前缀。您需要查询该命名空间中的元素;你不能只使用默认命名空间。
  • 响应是否有可能包含多个propstat 元素?或者那个 propstat 会有几个 propstatus 元素?您的 xml 中还可能缺少哪些元素?

标签: c# xml linq-to-xml


【解决方案1】:

你可以这样做。这有点笨拙但有效

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();

【讨论】:

    【解决方案2】:

    您可以在简单的查询中引入新的范围变量:

    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"
                    };
    

    注意:此答案假定您的响应将包含一个 propstat 元素,其中包含一个 prop 元素。

    【讨论】:

      【解决方案3】:

      你可以试试这个:

      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);
              });
          }
      }
      

      或者像这样:

      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);
          });
      });
      

      【讨论】:

        【解决方案4】:

        在您的情况下,我强烈建议使用XPath

        \\D:response 获取文档中的所有 D:response 元素

        \\D:response\D:href所有href元素

        \\D:response\D:propstat\D:prop\D:displayname 所有 displayName 元素

        \\D:response\D:propstat\D:prop\D:isFolderall isFolder 元素

        如果您需要相对路径,只需删除 \\。 请在我提供的链接中阅读有关 XPath 的更多信息。这绝对值得您投资。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多