2010-04-07 6 views
6

Ich versuche, XPath zu verwenden, um die Elemente auszuwählen, die eine Facette mit Location Werten haben, aber derzeit fehlschlagen meine Versuche, nur alle Elemente auszuwählen: Das System meldet glücklich, dass es 0 Elemente gefunden hat returns (stattdessen sollten die Knoten von einer foreach-Schleife verarbeitet werden). Ich würde mich freuen, wenn ich entweder meine ursprüngliche Anfrage stellen oder XPath überhaupt verwenden könnte.C# XPath, das nichts findet

XML

<?xml version="1.0" encoding="UTF-8" ?> 
<Collection Name="My Collection" SchemaVersion="1.0" xmlns="http://schemas.microsoft.com/collection/metadata/2009" xmlns:p="http://schemas.microsoft.com/livelabs/pivot/collection/2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<FacetCategories> 
    <FacetCategory Name="Current Address" Type="Location"/> 
    <FacetCategory Name="Previous Addresses" Type="Location" /> 
</FacetCategories> 
    <Items> 
     <Item Id="1" Name="John Doe"> 
      <Facets> 
       <Facet Name="Current Address"> 
        <Location Value="101 America Rd, A Dorm Rm 000, Chapel Hill, NC 27514" /> 
       </Facet> 
       <Facet Name="Previous Addresses"> 
        <Location Value="123 Anywhere Ln, Darien, CT 06820" /> 
        <Location Value="000 Foobar Rd, Cary, NC 27519" /> 
       </Facet> 
      </Facets> 
     </Item> 
    </Items> 
</Collection> 

C#

public void countItems(string fileName) 
{ 
    XmlDocument document = new XmlDocument(); 
    document.Load(fileName); 
    XmlNode root = document.DocumentElement; 
    XmlNodeList xnl = root.SelectNodes("//Item"); 
    Console.WriteLine(String.Format("Found {0} items" , xnl.Count)); 
} 

Es gibt mehr zu dem Verfahren als diese, aber da dies alles ist, was ich nehme an, dass das Problem liegt hier ausgefuehrt wird. Aufruf root.ChildNodes gibt genau FacetCategories und Items zurück, also bin ich völlig ratlos.

Danke für Ihre Hilfe!

Antwort

17

Ihr Root-Element hat einen Namensraum. Sie müssen einen Namespace-Resolver hinzufügen und die Elemente in Ihrer Abfrage voranstellen.

This article erklärt die Lösung. Ich habe Ihren Code so geändert, dass er 1 Ergebnis enthält.

public void countItems(string fileName) 
{ 
    XmlDocument document = new XmlDocument(); 
    document.Load(fileName); 
    XmlNode root = document.DocumentElement; 

    // create ns manager 
    XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(document.NameTable); 
    xmlnsManager.AddNamespace("def", "http://schemas.microsoft.com/collection/metadata/2009"); 

    // use ns manager 
    XmlNodeList xnl = root.SelectNodes("//def:Item", xmlnsManager); 
    Response.Write(String.Format("Found {0} items" , xnl.Count)); 
} 
6

Da Sie einen XML-Namespace auf dem Root-Knoten haben, gibt es nicht so etwas wie „Item“ in Ihrem XML-Dokument nur „[Namespace]: Item“, also wenn für einen Knoten mit XPath suchen, Sie müssen den Namespace angeben.

Wenn Sie das nicht mögen, können Sie die Funktion local-name() verwenden, um alle Elemente abzugleichen, deren lokaler Name (der Name Teil außer dem Präfix) der Wert ist, den Sie suchen. Es ist ein bisschen hässlich Syntax, aber es funktioniert.

XmlNodeList xnl = root.SelectNodes("//*[local-name()='Item']"); 
Verwandte Themen