2010-04-07 7 views
6

J'essaie d'utiliser XPath pour sélectionner les éléments qui ont une facette avec Location valeurs, mais actuellement mes tentatives même de simplement sélectionner tous les éléments échouent: Le système signale heureusement qu'il a trouvé 0 articles, puis renvoie (à la place les noeuds doivent être traités par une boucle foreach). J'apprécierais l'aide soit en faisant ma requête originale ou juste en faisant fonctionner XPath du tout.C# XPath ne trouve rien

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

Il y a plus à la méthode que cela, mais puisque c'est tout ce qui se fait courir je suppose que le problème se trouve ici. Appeler root.ChildNodes renvoie exactement FacetCategories et Items, donc je suis complètement à perte.

Merci pour votre aide!

Répondre

17

Votre élément racine a un espace de nom. Vous devrez ajouter un résolveur d'espace de noms et préfixer les éléments dans votre requête.

This article explique la solution. J'ai modifié votre code pour qu'il obtienne 1 résultat.

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

Parce que vous avez un espace de noms XML sur votre nœud racine, il n'y a pas une telle chose comme « Point » dans votre document XML, que « [namespace]: Item », donc lors de la recherche d'un noeud avec XPath, vous devez spécifier l'espace de noms.

Si vous n'aimez pas cela, vous pouvez utiliser la fonction nom-local() pour faire correspondre tous les éléments dont le nom local (la partie du nom autre que le préfixe) est la valeur que vous recherchez. C'est une syntaxe un peu moche, mais ça marche.

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