c # .net xpath не выбирает элементы при обходе - PullRequest
1 голос
/ 08 июня 2011

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

XML

<?xml version="1.0" encoding="UTF-16"?>
<Presentation>
    <Filename>Name of file</Filename>
    <version>1.2</version>
    <threshold>23</threshold> <!-- gives number of slides -->
    <Slides>
        <Slide id="slide id">
            <Filename>Name of file</Filename>
            <Title>Title of slide</Title>
        </Slide>
        <Slide id="slide id">
            <Filename>Name of file</Filename>
            <Title>Title of slide</Title>
            <quizobjects>
                <quizobject id="1">
                <filename>Name of quiz</filename>
            </quizobjects>
        </Slide>
        <Slide id="slide id">
            <Filename>Name of file</Filename>
            <Title>Title of slide</Title>
        </Slide>
        ...etc
     </Slides>
</Presentation>

Вот пример XML,Я просматриваю слайды, считая их, а также подсчитывая викторины.(Это возвращает правильные числа) Однако, когда я просматриваю все слайды, пытаясь найти местоположение каждого теста в узле Слайдов, он никогда не попадает ни в один из объектов викторины.

C #

int numSlides;

XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlToParse.Text); //pass in xml string
XmlElement root = doc.DocumentElement;

//get number of slides from threshold node
numSlides = Convert.ToInt32(root.SelectSingleNode("//threshold").InnerText);

//get number of quizzes/slides
XmlNodeList xnQuiz = root.SelectNodes("/Presentation/Slides/Slide/quizobjects"); //returns 7
XmlNodeList xnList = root.SelectNodes("/Presentation/Slides/Slide");

int[] quizLocArray = new int[xnQuiz.Count]; //create array to hold location of quizzes

int j = 0;
//find index of quizzes in slide list
for(int i = 0; i < xnList.Count; i++)
{
    XmlNode quiz = xnList[i].SelectSingleNode("/quizobjects");
    if(quiz != null) //stepping through quiz always equals null
    {
        quizLocArray[j] = (i + 1);
        j++;
    }
}

Вывод

numSlides / Общее количество слайдов в XML: 23

xnQuiz.Count / Общее количество тестов вXML: 7

String.Join(",", quizLocArray) / Массив индексов опросов в слайд-листе: 0,0,0,0,0,0,0

Ответы [ 3 ]

1 голос
/ 08 июня 2011

Похоже, что ваши данные XML не отформатированы должным образом, так как вы пропускаете закрывающий </quizobject>. Я собираюсь пойти дальше и предположить, что это просто опечатка.

Вам нужно изменить запрос XPath с SelectSingleNode("/quizobjects") на SelectSingleNode("quizobjects"), чтобы получить нужный элемент XML.

Файл Presentation.xml:

<Presentation>
  <Filename>Name of file</Filename>
  <version>1.2</version>
  <threshold>23</threshold>

  <!-- gives number of slides -->
  <Slides>
    <Slide id="slide id">
      <Filename>Name of file</Filename>
      <Title>Title of slide</Title>
    </Slide>
    <Slide id="slide id">
      <Filename>Name of file</Filename>
      <Title>Title of slide</Title>
      <quizobjects>
        <quizobject id="1">
          <filename>Name of quiz</filename>
        </quizobject>
      </quizobjects>
    </Slide>
    <Slide id="slide id">
      <Filename>Name of file</Filename>
      <Title>Title of slide</Title>
    </Slide>
  </Slides>

</Presentation>

C # Код:

XmlDocument doc     = new XmlDocument();

try
{
    using (var reader = XmlReader.Create("Presentation.xml"))
    {
        int numSlides;

        doc.Load(reader);

        XmlElement root = doc.DocumentElement;

        //get number of slides from threshold node
        numSlides = Convert.ToInt32(root.SelectSingleNode("//threshold").InnerText);

        //get number of quizzes/slides
        XmlNodeList xnQuiz = root.SelectNodes("/Presentation/Slides/Slide/quizobjects");
        XmlNodeList xnList = root.SelectNodes("/Presentation/Slides/Slide");

        //create array to hold location of quizzes
        int[] quizLocArray = new int[xnQuiz.Count];

        int j = 0;

        //find index of quizzes in slide list
        for (int i = 0; i < xnList.Count; i++)
        {
            XmlNode quiz = xnList[i].SelectSingleNode("quizobjects");
            if (quiz != null)
            {
                quizLocArray[j] = (i + 1);
                j++;
            }
        }
    }
}
catch (Exception exception)
{
    Console.WriteLine(exception.Message);
}
1 голос
/ 08 июня 2011

Просто замените '/ quizobjects' на 'quizobjects' в выражении:

XmlNode quiz = xnList[i].SelectSingleNode("/quizobjects");

Надеюсь, это будет работать ..

, когда путь начинается с / он всегда учитывает егокак абсолютный путь.Вот почему вы не получаете элемент.

1 голос
/ 08 июня 2011

Две проблемы:

  • В вашем примере XML, /Presentation/Slides/Slide[id='slide id']/quizobjects/quizobject не имеет конечного тега (и не является пустым тегом)
  • Ваш последний XPath для quizobjects имеет дополнительные /.Измените его на "quizobjects", и оно будет работать

Измененный код:

for(int i = 0; i < xnList.Count; i++)
{
    XmlNode quiz = xnList[i].SelectSingleNode("quizobjects"); // Changed from "/quizobjects"
    if(quiz != null) //stepping through quiz always equals null
    {
        quizLocArray[j] = (i + 1);
        j++;
    }
}
...