Справка по XPATH: поиск узлов XML в пространстве имен с помощью XPathNodeIterator

У меня возникли проблемы с поиском правильного синтаксиса XPATH для получения нужных мне узлов с помощью этого XML-файла. Во-первых, в XML нет NameSPace, поэтому мне нужно добавить его в код. Я думаю, что это влияет на мой XPATH.

У меня есть файл XML, который выглядит так:

<configuration xmlns="http://schemas.microsoft.com/support/2003/02/config">
  <name>Content</name>
  <description>Desc</description>
  <lastModifiedBy>Me</lastModifiedBy>
  <lastModifiedDate>2011-04-18T14:05:00</lastModifiedDate>
  <section name="MaintenanceNotices">
    <key name="MaintenanceNote1" value="The Title Value" />
    <link id="1234" type="5" href="" target="_self" name="MaintenanceNote1a">
      <description>Description</description>
    </link>
  </section>
</configuration>

Итак, для XPATH, если я хочу получить значение NODE «NAME» в элементе «CONFIGURATION», я предполагаю, что буду использовать этот XPATH:

/configuration/name

но иногда мне нужно добавить ns: к нему:

/ns:configuration/ns:name

И тогда я могу найти значение элемента следующим образом:

while (xmlNodeIterator.MoveNext()) {
    result += xmlNodeIterator.Current.SelectSingleNode("name", nsmgr).ToString();
}

Но это не работает для меня вообще. Он не найдет никаких значений в XML, независимо от того, какой xpath я пытаюсь использовать. Вот мой код:

    private string GetXML()
    {
        string result = string.Empty;
        string fileName = "Content.xml";
        string filePath = "C:\\Content\\{0}";

        XPathDocument xdoc = new XPathDocument(string.Format(filePath, fileName));

        var nav = xdoc.CreateNavigator();

        XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
        nsmgr.AddNamespace("ns", "http://schemas.microsoft.com/taxonomy/2003/1");
        nsmgr.AddNamespace("gds", "http://support.microsoft.com/common/schemas/gdsPage/1/");

        string sectionName = "MaintenanceNotices";
        string xpath = "/configuration"; 

        //  section[name={0}]"; ///key[name=MaintenanceNote1]/";

        XPathNodeIterator xmlNodeIterator = nav.Select(string.Format(xpath, sectionName), nsmgr);

        while (xmlNodeIterator.MoveNext())
        {
            result += xmlNodeIterator.Current.SelectSingleNode("name", nsmgr).ToString();
        }

        return result;
    }

Можете ли вы увидеть какие-либо проблемы или предложить свой синтаксис Xpath?

Спасибо.


person Shawn J. Molloy    schedule 23.03.2011    source источник
comment
возможный дубликат XPath не работает должным образом в C#   -  person John Saunders    schedule 23.03.2011


Ответы (2)


Я не вижу ничего плохого в вашем XPath, за исключением того, что вы никогда не регистрируете пространство имен, в котором находятся узлы вашего документа:

"http://schemas.microsoft.com/support/2003/02/config"

Похоже, вы уже знаете, как это сделать на своем языке (используя AddNamespace), так что, возможно, это просто недосмотр. Если вам нужна дополнительная информация, это должно помочь:

person Wayne    schedule 23.03.2011
comment
Понятно, мне нужно добавить ns: перед каждым узлом, чтобы сообщить xpath, что искомый узел находится в указанном мной пространстве имен. Я попробую. Спасибо. - person Shawn J. Molloy; 23.03.2011
comment
@Shawn - Если я что-то не упустил, вы привязываете ns к http://schemas.microsoft.com/taxonomy/2003/1, но ваш документ использует пространство имен http://schemas.microsoft.com/support/2003/02/config. - person Wayne; 23.03.2011
comment
Мое пространство имен было неправильным. В этом была проблема. Уважайте пространство имен! Спасибо много. - person Shawn J. Molloy; 23.03.2011
comment
Хорошая точка зрения. Я буду иметь это в виду. Я принял ответ Любурка и буду делать это для всех своих сообщений с этого момента. Спасибо. - person Shawn J. Molloy; 25.03.2011

Как сказал @lwburk, вам нужно зарегистрировать пространство имен.

Оператор выбора должен быть:

var xmlNodeIterator = nav.Select("/ns:configuration/ns:name", nsmgr)
person Richard Schneider    schedule 23.03.2011