Почему SelectSingleNode возвращает значение null?

Я работаю с документом XML, который содержит структуру, похожую на эту:

<MT>
  <Events>
    <event id="1">
      <field name="blah" value="a_value" type="atype" />
      .
      .
      .
     </event>
   </Events>
 </MT>

В настоящее время я загружаю это из файла в XML-документ следующим образом:

XmlDocument xdoc = new XmlDocument();
xdoc.Load("somefile.xml");  //Successfully loads btw

Однако у меня возникла проблема и только с этим конкретным документом, когда я пытаюсь запустить следующую строку кода:

xdoc.SelectSingleNode("//event[@id='1']"); //This returns a null 

Я на правильном пути, предполагая, что это возвращает null из-за проблемы с использованием атрибута с именем «id», или я что-то упустил в коде?


person Todd Richardson    schedule 30.04.2009    source источник


Ответы (1)


Я не могу воспроизвести это с помощью файла XML

<MT>
  <Events>
    <event id="1">
      <field name="blah" value="a_value" type="atype" />
     </event>
   </Events>
</MT>

И код

XmlDocument doc = new XmlDocument();
doc.Load(@"C:\test.xml");

XmlNode node = doc.SelectSingleNode("//event[@id='1']");

Это возвращает ненулевой узел, как и ожидалось.

Обновить

После добавления xmlns="example.org" к элементу <MT> мне пришлось настроить диспетчер пространства имен для XPath и использовать пространство имен для события. По какой-то причине не удалось заставить работать пространство имен по умолчанию.

XmlDocument doc = new XmlDocument();
doc.Load(@"D:\test.xml");

XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
manager.AddNamespace("e", "http://example.org");

XmlNode node = doc.SelectSingleNode("//e:event[@id='1']", manager);

Одна вещь смутила меня, когда я пытался заставить это работать. Зачем XmlNamespaceManager нужен XmlNameTable из документа, если не для того, чтобы узнать, какие пространства имен он содержит? Например, зачем мне определять NameTable и пространство имен? Буду признателен, если кто-нибудь, кто знает, может оставить короткий комментарий.

person Mikko Rantanen    schedule 30.04.2009
comment
Отвечая на мой собственный вопрос. XmlNameTable используется для оптимизации сравнения строк, и я предполагаю, что причина, по которой вы можете предоставить XmlNamespaceManager существующую таблицу имен, позволяет быстро сравнивать с элементами XmlDocument, поскольку они затем совместно используют NameTable. - person Mikko Rantanen; 01.05.2009
comment
Ваше обновление, кажется, имеет смысл. Я пытался создать сокращенную форму xml и забыл опубликовать пространство имен. Спасибо, что нашли дополнительное время, чтобы попытаться понять это. Как только я удалил пространство имен из исходного xml, все работает как надо. Определенно стоит больше изучить пространство имен System.Xml. - person Todd Richardson; 01.05.2009