Я пытаюсь использовать XPath для выбора объектов, которые имеют фасет с Location
значения, но в настоящее время мои попытки даже, чтобы просто выбрать весь сбой объектов: система счастливо сообщает, что нашла 0 объектов, затем возвращается (вместо этого, узлы должны быть обработаны a foreach
цикл). Я ценил бы справку или создание моего исходного запроса или просто то, чтобы заставлять 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
, таким образом, я полностью в недоумении.
Спасибо за помощь!
Ваш корневой элемент имеет пространство имен. Вам нужно будет добавить преобразователь пространства имен и префикс элементов в вашем запросе.
Эта статья объясняет решение. Я изменил ваш код, чтобы получить 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));
}
Поскольку у вас есть пространство имен XML на корневом узле, в вашем XML-документе нет такого понятия, как «элемент», только «[пространство имен]: элемент», поэтому при поиске узла с помощью XPath необходимо указать пространство имен.
Если вам это не нравится, вы можете использовать функцию local-name () для сопоставления всех элементов, чье локальное имя (часть имени, отличная от префикса) является значением, которое вы ищете. Это немного уродливый синтаксис, но он работает.
XmlNodeList xnl = root.SelectNodes("//*[local-name()='Item']");