2010-04-07 6 views
6

Я пытаюсь использовать XPath для выбора элементов с фасеткой с Location значениями, но в настоящее время мои попытки даже просто выбрать все элементы не срабатывают: система с радостью сообщает, что она обнаружила 0 элементов, затем возвращает (вместо этого узлы должны обрабатываться петлей foreach). Я был бы признателен за помощь в подготовке моего первоначального запроса или просто при получении XPath.C# XPath не находит ничего

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

Там больше метода, чем это, но так как это все, что получает запустить Я предполагаю, что проблема лежит здесь. Вызов root.ChildNodes точно возвращает FacetCategories и Items, поэтому я полностью в растерянности.

Благодарим за помощь!

ответ

17

Ваш корневой элемент имеет пространство имен. Вам нужно будет добавить распознаватель пространства имен и префикс элементов в вашем запросе.

This article объясняет решение. Я изменил код, чтобы он получил 1 результат.

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

Поскольку у вас есть пространство имен XML на корневом узле, нет такого понятия, как «Пункт» в документе XML, только «[имен]: Пункт», поэтому при поиске узла с помощью XPath вам нужно указать пространство имен.

Если вам это не нравится, вы можете использовать функцию local-name() для соответствия всем элементам, локальное имя которых (имя, отличное от префикса) - это значение, которое вы ищете. Это немного уродливый синтаксис, но он работает.

XmlNodeList xnl = root.SelectNodes("//*[local-name()='Item']"); 
Смежные вопросы