Почему XPathNodeIterator не находит нужный путь? - PullRequest
0 голосов
/ 07 ноября 2019

У меня проблема с XPathNodeIterator, получающим данные с указанного пути. При отладке pNav имеет все значения из файла xml. Однако итератор показывает счетчик 0. Он никогда не входит в цикл while. Любая помощь будет оценена.

C #

XPathDocument pdoc = new XPathDocument("Courses.xml");
XPathNavigator pNav = pdoc.CreateNavigator();
XPathNodeIterator iterator = pNav.Select("/Courses/Course");
while (iterator.MoveNext())
{
   XPathNodeIterator it = iterator.Current.Select("Name");
   it.MoveNext();
   string courseName = it.Current.Value;
   it = iterator.Current.Select("Code");
   it.MoveNext();
   string courseCode = it.Current.Value;
   Console.WriteLine("{0} {1}", courseName, courseCode);
}

XML:

<Courses xmlns="http://xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="Courses.xsd">
<Course>
<Code Undergrad="240"/>
<Name>Biology</Name>
<Instructor>
<Name>
   <First>John</First>
   <Last>Doe</Last>
</Name>
<Contact>
   <Phone>898-989-8989</Phone>
</Contact>
</Instructor>
<Room>515</Room>
</Course>
</Courses>

Я ожидаю, что результат будет

Name = Biology, Code = 240

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

Поскольку в вашем XML-файле есть

xmlns="http://xml"

, вам нужно добавить XmlNamespaceManager, чтобы навигатор мог найти узлы. Если вы удалите xmlns="http://xml" из своего XML, вам не нужно будет использовать XmlNamespaceManager.

. Также метод Select возвращает коллекцию узлов - вам нужно вызвать SelectSingleNode, чтобы получитьузел, который вы хотите. EG

XPathDocument pdoc = new XPathDocument("Courses.xml");
XPathNavigator pNav = pdoc.CreateNavigator();

var manager = new XmlNamespaceManager(pNav.NameTable);
manager.AddNamespace("cs", "http://xml");

XPathNodeIterator iterator = pNav.Select("/cs:Courses/cs:Course", manager);

while(iterator.MoveNext())
{
    var nameNode = iterator.Current.SelectSingleNode("cs:Name", manager);
    string courseName = nameNode.Value;

    var codeNode = iterator.Current.SelectSingleNode("cs:Code", manager);

    codeNode.MoveToFirstAttribute();

    string courseCode = codeNode.Value;
    Console.WriteLine("{0} {1}", courseName, courseCode);
}

Когда вы попадаете на элемент Code, вам нужно перейти к первому атрибуту, чтобы получить значение, в противном случае свойство Value вернет пустую строку

0 голосов
/ 07 ноября 2019

Необходимо передать распознаватель пространства имен в метод выбора:

const string xml = @"
    <Courses xmlns=""http://xml"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:schemaLocation=""Courses.xsd"">
        <Course>
            <Code Undergrad=""240""/>
            <Name>Biology</Name>
            <Instructor>
                <Name>
                    <First>John</First>
                    <Last>Doe</Last>
                </Name>
                <Contact>
                <Phone>898-989-8989</Phone>
                </Contact>
            </Instructor>
            <Room>515</Room>
        </Course>
        <Course>
            <Code Undergrad=""000""/>
            <Name>Math</Name>
            <Instructor>
                <Name>
                    <First>John</First>
                    <Last>Doe</Last>
                </Name>
                <Contact>
                <Phone>898-989-8989</Phone>
                </Contact>
            </Instructor>
            <Room>515</Room>
        </Course>
    </Courses>";

using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(xml)))
{
    var pdoc = new XPathDocument(stream);
    var pNav = pdoc.CreateNavigator();

    var manager = new XmlNamespaceManager(pNav.NameTable);
    manager.AddNamespace("cs", "http://xml");

    var iterator = pNav.Select("/cs:Courses/cs:Course", manager);

    foreach (XPathNavigator node in iterator)
    {
        var courseName = node.SelectSingleNode("cs:Name", manager)?.Value;
        var courseCode = node.SelectSingleNode("cs:Code", manager)?.GetAttribute("Undergrad", string.Empty);

        Console.WriteLine("{0} {1}", courseName, courseCode);
    }
}
...