XmlDocument и получение определенных атрибутов с помощью xPath

Я видел здесь несколько примеров, где Xpath используется в сочетании с XmlDocument для получения определенного атрибута из узла XmlDocument.... Пример

Console.WriteLine(xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/@name").Value.ToString());

По какой-то причине я получаю «Ссылка на объект не указывает на экземпляр объекта». исключение. Всякий раз, когда я сталкиваюсь с этой конкретной строкой кода. У меня есть небольшое тестовое приложение, которое я настроил для проверки разных вещей, прежде чем помещать их в свой основной проект...

Вот код для этого...

namespace ReadXml
{
    class Program
    {
        static void Main(string[] args)
        {
            //string fulXmlPath =     System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/templateExample.xml");
            XDocument xDocument = XDocument.Load("C:\\Users\\derekww\\Documents\\XML Documents\\templateExample.xml");
            XElement elem = xDocument.Element("dataTemplateSpecification"); ;
            XmlDocument xmlDocument = new XmlDocument();
            StreamReader file = new StreamReader("C:\\Users\\derekww\\Documents\\XML Documents\\templateExample.xml");

            xmlDocument.Load(file);

            //XmlDocument theDoc = new XmlDocument();
            //using (var xmlReader = xDocument.CreateReader())
            //{
            //    xmlDocument.Load(xmlReader);
            //}

            //Console.WriteLine(elem.ToString());
            XmlNode xNode = xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element");
            Console.WriteLine("WORK PLEASE!!!! {0}", xNode.Value.ToString());
            //Console.WriteLine(xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/@name").Value.ToString());
            //Console.WriteLine("This better Work>>>> {0}", xmlDocument.Attributes["/dataTemplateSpecification/templates/template/elements/element/@name"].Value);
            Console.ReadLine();
            //Console.WriteLine("This better Work>>>> {0}", xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/@name").Value);
            //foreach (String AttVal in xmlDocument.SelectSingleNode("//dataTemplateSpecification/templates/template/elements/element/@name").Value)
            {
                //Console.WriteLine("This better Work>>>> {0}", AttVal);
            }
        }
    }
}

Вот часть XML, который я использовал...

    <?xml version="1.0" encoding="utf-8"?>
    <dataTemplateSpecification id="id1" name="name1" xmlns="http://EADIS.upmc.com      /DataTemplateSpecification.xsd">
      <description xmlns="">
        <html>text</html>
      </description>
      <templates xmlns="">
        <template>
          <elements>
            <element id="element0" name="PatientId" display="Patient ID"  dataType="String" value="0101010111111" visable="false" readOnly="true">
              <validation>
                <rules>
                  <rule id="0" test="#element0.value == ''">
                    <fail>
                      <html><b>Patient ID is null, value must be present</b></html>
                    </fail>
                  </rule>
                </rules>
              </validation>
            </element>
           </elements>
          </template>
         <templates>

Я только что показал вам ту часть, которая вам нужна для понимания структуры xml. Уверяю вас, что она хорошо сформирована. Я думаю, что задавал этот вопрос раньше, но так или иначе он не был опубликован (может быть, я забыл, кто знает). Любая помощь в этом будет принята с благодарностью. Если я найду причину, по которой это не работает, я обязательно сообщу вам, ребята.

Спасибо.


person SoftwareSavant    schedule 05.07.2011    source источник
comment
Удалите ненужную ненормативную лексику из своего кода, сделайте отступ в примерах кода на 4 пробела, чтобы они отображались правильно, и прочтите XmlNamespaceManager   -  person Tomalak    schedule 05.07.2011
comment
возможный дубликат Использование Xpath с пространством имен по умолчанию в C#   -  person Tomalak    schedule 05.07.2011
comment
Почему бы вам не придерживаться Linq to XML? Я думаю, что это намного проще и понятнее.   -  person Saeed Neamati    schedule 05.07.2011
comment
В порядке. Просто разберись. Спасибо Томалак. После небольшого исследования вам, очевидно, нужно добавить namspaceManager к вашим запросам Xpath. Для этого вам нужно добавить XmlNameSpaceManger, префикс и т. д. Еще раз спасибо.   -  person SoftwareSavant    schedule 05.07.2011
comment
Это то, что я хотел бы сделать, Саид. Просто используйте Xdoc и немного Linq to XML. Короткий ответ, офисная политика. Один из моих начальников любит linq, другой по разным причинам его презирает. Этот проект для второго босса. Оба хорошие парни, просто разные философии, я полагаю. Я просто рад, что узнал новый способ сделать то же самое. Спасибо еще раз за помощь.   -  person SoftwareSavant    schedule 05.07.2011
comment
@Dmain: +1 за то, что разобрался сам. Если вы опубликуете соответствующую часть своего фиксированного кода в качестве ответа, я бы тоже проголосовал за это.   -  person Tomalak    schedule 05.07.2011
comment
Я думал, что понял это. Я только что понял, что нет. Я не получаю тех результатов, на которые рассчитывал. Я не возвращаю никаких узлов в свой xmlNodeList. Я не понимаю, что происходит. Позвольте мне задать вам вопрос, если где-нибудь в файле .xml есть какие-либо случайные атрибуты xmlns, повлияет ли это каким-либо образом на диспетчер пространства имен. Даже если значение XMLNS равно нулю?   -  person SoftwareSavant    schedule 06.07.2011


Ответы (2)


Почему вы не можете использовать это XPath:

xmlDocument.SelectSingleNode("//templates/template/elements/element/@name").Value
person VMAtm    schedule 05.07.2011
comment
Поскольку XML содержит пространство имен по умолчанию, и это выражение XPath ничего не вернет. ;) - person Tomalak; 05.07.2011
comment
@Tomalak Ты пробовал это, прежде чем сказать это? У меня работает для этого xml. - person VMAtm; 05.07.2011
comment
О, я проглядел бродячего xmlns="". Моя вина. (и +1, затем) - person Tomalak; 05.07.2011
comment
Я только что посмотрел на вызов xmlDocument.SelectSingleNode() коллег. Он также не настраивает менеджера пространства имен, и его работы блестящи. Чего-то здесь не хватает. Возможно, я обнаружил недостаток в одной из библиотек Microsoft. - person SoftwareSavant; 06.07.2011

Вам необходимо указать пространство имен XML-файла в коде.
Дополнительную информацию см. здесь: Как выбрать корневой узел xml, если корневой узел имеет атрибут?

person Daniel Hilgarth    schedule 05.07.2011
comment
Действительно ли необходимо публиковать ответы-заглушки, чтобы быть самым быстрым? :-\ - person Tomalak; 05.07.2011
comment
Это не заглушка. Он говорит ему, что делать, чтобы решить его проблему. - person Daniel Hilgarth; 05.07.2011
comment
Это был заполнитель, пока вы не удалили детали следуют…. ;-) - person Tomalak; 05.07.2011
comment
Нет, не было. Первое предложение уже говорит ему, как решить его проблему. Эта фраза без изменений. Остальное для его удобства... - person Daniel Hilgarth; 05.07.2011