Как получить доступ к разным XML-узлам, которые имеют одного и того же родителя?

#c# #xml #linq #xpath #xmldocument

#c# #xml — файл #linq #xpath — путь #xmldocument

Вопрос:

У меня есть XML-файл, подобный этому:

 <Document>
   <Tests>
      <Test>
          <Name>A</Name>
          <Value>1</Value>
      </Test>
      <Test>
          <Name>A</Name>
          <Value>2</Value>
      </Test>
      <Test>
          <Name>B</Name>
          <Value>10</Value>
      </Test>
      <Test>
          <Name>B</Name>
          <Value>20</Value>
      </Test>
   </Tests>
</Document>
  

Я создал класс для хранения данных для каждого Test узла:

 public class TestData
{
public string TestName {get; set;}
public float TestValue {get; set;}
}
  

И я считываю данные, используя XPATH, вот так ( ztr это экземпляр XmlDocument , и я уже знаю имя Test , которое собираюсь прочитать, поскольку оно было введено в ListView):

     public TestData GetTestData(string testName)
    {
        TestData data = new TestData();           

        data.TestName = testName;
        data.TestValue = float.Parse(ztr.SelectSingleNode("/Document/Tests/Test[Name = '"   testName   "')]/Value").InnerText, CultureInfo.InvariantCulture);

        return data;
    }
  

Теперь проблема в том, что если я хочу составить список данных, поскольку List<TestData> каждый TestData ссылается только на первое появление тестового узла в XML-файле. Я имею в виду, давайте представим, что у меня есть ListView, который уже заполнен именами всех Test узлов в моем XML-файле. в данном случае это что-то вроде этого:

ListView = A,A,B,B и затем я копирую все имена в массив string[]

И я использую этот код, чтобы прочитать их все за один раз:

 private List<TestData> GetAllData()
{
    List<TestData> Datas = new List<TestData>();
    TestData data;

    foreach(string test in stringOfNames)
    {
       data = new TestData;
       data = GetTestData(test);
       Datas.add(data);
    }

    return Datas
}
  

Как я уже говорил вам, этот код не делает различий между разными Test . Он просто возвращает первое вхождение a, Test поэтому результатом для GetAllData() будет:

 Name     Value
A        1
A        1
B        10
B        10
  

НО я хочу, чтобы это было похоже

 Name     Value
A        1
A        2
B        10
B        20
  

Не могли бы вы, пожалуйста, сказать мне, что я делаю не так? и как решить эту проблему?

P.S. Я написал все коды только здесь, в stackoverflow…они не скомпилированы, просто представьте, что они отлично работают: D

Комментарии:

1. Итак … вам нужны накопленные значения?

Ответ №1:

Измените свой GetTestData() метод (и его вызывающий объект соответственно):

     public TestData GetTestData(string testName, int pos) 
    { 
        TestData data = new TestData();            

        data.TestName = testName; 
        data.TestValue 
         = float.Parse(
ztr.SelectSingleNode("/Document/Tests/Test[Name = '"   testName   "')]["   pos   "]/Value").InnerText, CultureInfo.InvariantCulture); 

        return data; 
    }
  

Ответ №2:

Вместо того, чтобы использовать SelectSingleNode , используйте SelectNodes вместо этого, я думаю, вашего текущего xpath должно быть достаточно. Вам придется переписать свой GetTestData метод для обработки итерации по XmlNodeList , чтобы разобрать правильное float значение.