C # XPath ничего не находя - PullRequest
       19

C # XPath ничего не находя

6 голосов
/ 07 апреля 2010

Я пытаюсь использовать XPath для выбора элементов, имеющих фасет со значениями Location, но в настоящее время мои попытки даже просто выделить все элементы не удаются: система с радостью сообщает, что обнаружила 0 элементов, а затем возвращает (вместо узлы должны обрабатываться циклом 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, поэтому я полностью в замешательстве.

Спасибо за вашу помощь!

Ответы [ 2 ]

18 голосов
/ 07 апреля 2010

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

Эта статья объясняет решение.Я изменил ваш код, чтобы он получил 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));
}
9 голосов
/ 07 апреля 2010

Поскольку у вас есть пространство имен XML на вашем корневом узле, в вашем документе XML нет такой вещи, как «Элемент», только «[namespace]: Item», поэтому при поиске узла с помощью XPath вам необходимо указать пространство имен.

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

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