Чтение XML между двумя дочерними узлами - PullRequest
0 голосов
/ 05 мая 2011

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

Способ работы приложения заключается в том, что имена всех xmls в папке добавляются в выпадающий список после выбора файла в выпадающем списке, затем в другое поле со списком добавляются все номера тестовых циклов, которые содержатся в этом XML. Затем вы выбираете число в поле cmobox и затем нажимаете кнопку, а затем я хочу, чтобы все значения атрибутов filename и hashcode были затем записаны в список. То есть если существует 20 значений имени файла и 20 значений хэш-кода, в списке должно быть 40 элементов.

Единственная функция, которая не работает - это добавление в список один.

void HashMe::AddToListBox()
{
    String^ SelectedFile = comboBox1->SelectedItem->ToString();
    String^ SearchString = "*" + SelectedFile + "*.XML";
    int SelectedTC = int::Parse(comboBox2->SelectedItem->ToString());

    try
    {
        array<String^>^ FullPaths = IO::Directory::GetFiles("E:\\XML Folder\\", SearchString, System::IO::SearchOption::AllDirectories);
        int number = FullPaths->GetLength(0);

        for (int x = 0; x < number; x++)
        {
            String^ FullPath = FullPaths[x];

            XPathNavigator^ Root = XPathDocument(FullPath).CreateNavigator();
            for each (XPathNavigator^ Nav in Root->Select(L"//TestCycle[@Number = '" + SelectedTC + "']"))
            {
                listBox4->Items->Add(Nav->GetAttribute(L"FileName",String::Empty)).ToString();
                listBox4->Items->Add(Nav->GetAttribute(L"HashCode",String::Empty)).ToString();
            }
        }
    }
    catch (Exception^ e)
    {
        MessageBox::Show(e->ToString());
    }
}

Структура файла XML выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<Project Name="New">
  <TestCycle Number="1">
    <Files>
      <FileName File="C:\Users\brandonm\Documents\asd.xps" />
      <HashCode Code="AB-B5-85-EC-FE-C4-E2-41-09-6A-A8-77-69-A9-8D-1F" />
      <FileName File="C:\Users\brandonm\Documents\asdas.xps" />
      <HashCode Code="7F-30-12-76-C8-80-CA-03-EC-71-12-49-9E-56-9D-D8" />
      <FileName File="C:\Users\brandonm\Documents\asdasdasd" />
      <HashCode Code="09-37-69-EF-36-3B-FD-42-D2-37-2D-70-74-A6-ED-BA" />
    </Files>
  </TestCycle>
  <Project Name="New">
    <TestCycle Number="2">
      <Files>
        <FileName FileName="C:\Users\brandonm\Documents\asd.xps" />
        <HashCode HashCode="AB-B5-85-EC-FE-C4-E2-41-09-6A-A8-77-69-A9-8D-1F" />
        <FileName FileName="C:\Users\brandonm\Documents\asdas.xps" />
        <HashCode HashCode="7F-30-12-76-C8-80-CA-03-EC-71-12-49-9E-56-9D-D8" />
        <FileName FileName="C:\Users\brandonm\Documents\asdasd.xps" />
        <HashCode HashCode="E4-EF-33-AE-24-23-00-37-FD-E2-20-60-5E-68-C0-54" />
      </Files>
    </TestCycle>
  </Project>

Любая помощь будет принята с благодарностью. Я думаю, что может быть проблема с моими запросами XPath. Спасибо

1 Ответ

0 голосов
/ 06 мая 2011

Сначала вам нужно исправить свой XML, так как он непоследователен и деформирован:

  • У вас больше открытых Project элементов, чем закрытых элементов
  • У вас нет рутаэлемент, который будет содержать каждый Project элемент
  • Под TestCycle # 1 именем вашего FileName элемента 'будет File, тогда как при TestCycle # 2 вашим FileName именем атрибута элемента является FileName;согласовать эти
  • в TestCycle # 1 имя вашего HashCode элемента 'будет иметь атрибут Code, тогда как в TestCycle # 2 имя вашего HashCode элемента' будет HashCode;согласовать эти

Я предполагаю, что вы исправите это следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<Projects>
  <Project Name="New">
    <TestCycle Number="1">
      <Files>
        <FileName File="C:\Users\brandonm\Documents\asd.xps" />
        <HashCode Code="AB-B5-85-EC-FE-C4-E2-41-09-6A-A8-77-69-A9-8D-1F" />
        <FileName File="C:\Users\brandonm\Documents\asdas.xps" />
        <HashCode Code="7F-30-12-76-C8-80-CA-03-EC-71-12-49-9E-56-9D-D8" />
        <FileName File="C:\Users\brandonm\Documents\asdasdasd" />
        <HashCode Code="09-37-69-EF-36-3B-FD-42-D2-37-2D-70-74-A6-ED-BA" />
      </Files>
    </TestCycle>
  </Project>
  <Project Name="New">
    <TestCycle Number="2">
      <Files>
        <FileName File="C:\Users\brandonm\Documents\asd.xps" />
        <HashCode Code="AB-B5-85-EC-FE-C4-E2-41-09-6A-A8-77-69-A9-8D-1F" />
        <FileName File="C:\Users\brandonm\Documents\asdas.xps" />
        <HashCode Code="7F-30-12-76-C8-80-CA-03-EC-71-12-49-9E-56-9D-D8" />
        <FileName File="C:\Users\brandonm\Documents\asdasd.xps" />
        <HashCode Code="E4-EF-33-AE-24-23-00-37-FD-E2-20-60-5E-68-C0-54" />
      </Files>
    </TestCycle>
  </Project>
</Projects>

Ваш код написан так, как будто FileName и HashCode являются атрибутами TestCycle, но на самом деле это элементы в TestCycle/Files с соответствующими атрибутами File и Code.Очевидно, ваш код здесь ошибочен;замените внутреннюю петлю for each на что-то вроде:

String^ fmt = L"//TestCycle[@Number = '{0}']/Files/FileName/@File | //TestCycle[@Number = '{0}']/Files/HashCode/@Code";
for each (XPathNavigator^ Nav in Root->Select(String::Format(fmt, SelectedTC)))
    listBox4->Items->Add(Nav->Value);

или

for each (XPathNavigator^ Cycle in Root->Select(String::Format(L"//TestCycle[@Number = '{0}']", SelectedTC)))
    for each (XPathNavigator^ Nav in Cycle->Select(L"Files/FileName/@File | Files/HashCode/@Code"))
        listBox4->Items->Add(Nav->Value);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...