0

私はLINQtoXMLを初めて使用し、次のクエリの作成を誰かが手伝ってくれるかどうか疑問に思っていました。

「404」を含む<response>子孫要素を含まないすべての要素を返したい。<status>

私のXMLを以下に示します。この場合、最初の<response>要素(および子孫)のみが返されます。

<multistatus xmlns="DAV:">
  <response>
    <href>/principals/users/test/</href>
    <propstat>
      <prop>
        <calendar-home-set xmlns="urn:ietf:params:xml:ns:caldav">
          <href xmlns="DAV:">/calendars/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9</href>
        </calendar-home-set>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response>
    <href>/principals/users/test/calendar-proxy-write/</href>
    <propstat>
      <prop>
        <calendar-home-set xmlns="urn:ietf:params:xml:ns:caldav" />
      </prop>
      <status>HTTP/1.1 404 Not Found</status>
    </propstat>
  </response>
  <response>
    <href>/principals/users/test/calendar-proxy-read/</href>
    <propstat>
      <prop>
        <calendar-home-set xmlns="urn:ietf:params:xml:ns:caldav" />
      </prop>
      <status>HTTP/1.1 404 Not Found</status>
    </propstat>
  </response>
</multistatus>
4

5 に答える 5

3

XMLが文字列変数に格納されていると仮定しますxml

XDocument document = XDocument.Parse(xml);
XNamespace ns = document.Root.GetDefaultNamespace();

var responsesExcept404s = document
    .Descendants(ns + "response")
    .Where(x => !x.Descendants(ns + "status")
                  .Single()
                  .Value.Contains("404"));

ns変数の使用法に注意してください。XMLには属性を介して設定されたデフォルトの名前空間があるため、LINQ to XMLを使用する場合(メソッドxmlnsなど)にその名前空間を指定する必要があります。Descendants()

次に、結果を繰り返し処理し、これを非常に便利にするために、結果をコンソールに出力します。

responsesExcept404s.ToList().ForEach(Console.WriteLine);
于 2012-07-27T21:29:20.607 に答える
2
XDocument xDoc = XDocument.Parse(xml);
XNamespace ns = XNamespace.Get("DAV:");
var responses = xDoc.Descendants(ns + "status")
                    .Where(s => !s.Value.Contains(" 404 "))
                    .Select(s => s.Parent.Parent);
于 2012-07-27T21:49:57.157 に答える
1

ここに行きます:(XPathで不正行為)

        XDocument xdoc = XDocument.Load(new FileStream("XMLFile2.xml", FileMode.Open, FileAccess.Read));
        XPathNavigator nav = xdoc.CreateNavigator();
        var nsm = new XmlNamespaceManager(nav.NameTable);            
        nsm.AddNamespace("s", "DAV:");
        var nodes = xdoc.XPathSelectElements("s:multistatus/s:response[.//*[name(.)='status' and .='HTTP/1.1 404 Not Found']]", nsm);
于 2012-07-27T21:43:09.360 に答える
0

これを試して:

Document doc = XDocument.Load(path);
       XNamespace nsd = doc.Root.GetDefaultNamespace();
        var res = doc.Descendants(nsd +"response");                

        var filteredEle = new List<XElement>();

                    foreach (var ele in res)
                    {
                        if (CheckEle(ele,nsd))
                        {
                            filteredEle.Add(ele);
                        }
                    }    


    private bool CheckEle(XElement ele, XNamespace nsd)
        {
            return ele.Element(nsd + "propstat").Element(nsd + "status").Value != "HTTP/1.1 404 Not Found";
        }
于 2012-07-27T21:10:17.213 に答える
0

以下に示すように、linqステートメントを使用できます。

XDocument doc = XDocument.Parse(xml);
List<XElement> responseWithOut404 = 
    (from element in doc.Descendants("response")
     let xElement = element.Descendants("status").First() 
     where !xElement.Value.Contains("404")
     select element)
     .ToList();
于 2012-07-27T21:42:04.263 に答える