2015-10-14 6 views
0

У меня сложный цикл, проходящий через узлы XML-документа. У меня есть документ, который имеет следующую иерархию:Итерация через XML-документ с несколькими поднодами

<?xml version="1.0" encoding="UTF-8"?> 
<TEMPONDERZOEK xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

<TRIES>3</TRIES> 
<RESULTATEN> 
    <INSTRUMENT> 
     <INSTRUMENT_CODE>SPOTCHEM EZ</INSTRUMENT_CODE> 
     <TEST_CODE>0</TEST_CODE> 
     <VLAG>1</VLAG> 
     <ANALYSES> 
     <ANALYSE> 
      <AFKORTING>BUN</AFKORTING> 
      <WAARDE>23.7</WAARDE> 
      <EENHEID>MMOL/L</EENHEID> 
     </ANALYSE> 
     <ANALYSE> 
      <AFKORTING>GLU</AFKORTING> 
      <WAARDE>15.0</WAARDE> 
      <EENHEID>MMOL/L</EENHEID> 
     </ANALYSE> 
     </ANALYSES> 
    </INSTRUMENT> 
    <INSTRUMENT> 
     <INSTRUMENT_CODE>SPOTCHEM EL</INSTRUMENT_CODE> 
     <TEST_CODE>1</TEST_CODE> 
     <VLAG>1</VLAG> 
     <ANALYSES> 
     <ANALYSE> 
      <AFKORTING>Na</AFKORTING> 
      <WAARDE> 152</WAARDE> 
      <EENHEID>mmol/L</EENHEID> 
     </ANALYSE> 
     <ANALYSE> 
      <AFKORTING>K</AFKORTING> 
      <WAARDE> 4.4</WAARDE> 
      <EENHEID>mmol/L</EENHEID> 
     </ANALYSE> 
     </ANALYSES> 
    </INSTRUMENT> 
</RESULTATEN> 
</TEMPONDERZOEK> 

я написал следующие C# код для перебирать документ:

// Get all fraudulent XML files 
     string[] fraudulentsArray = Directory.GetFiles(@"tempXML\fraudulent", "temp_*.xml"); 

     // Iterate through every XML file that has been collected 
     foreach (var x in fraudulentsArray) 
     { 
      XmlDocument xml = new XmlDocument(); 
      xml.Load(x); 

      // Get the first parent node 
      XmlNode resultaten = xml.SelectSingleNode("//RESULTATEN"); 

      // Get all the INSTRUMENT nodes in RESULTATEN 
      var instrumentNodes = resultaten.SelectNodes("//INSTRUMENT"); 

      // Loop through the instrument nodes 
      for (int i = 0; i < instrumentNodes.Count; i++) 
      { 
       // Get the values from nodes inside parent node INSTRUMENT and store them 
       xmlanalyse.INSTRUMENT_CODE = instrumentNodes[i].ChildNodes[0].InnerText; 
       xmlanalyse.TEST_CODE = instrumentNodes[i].ChildNodes[1].InnerText.ToInt(); 
       xmlanalyse.VLAG = instrumentNodes[i].ChildNodes[2].InnerText.ToInt(); 

       // Get the ANALYSES parent node 
       XmlNode analyses = instrumentNodes[i].SelectSingleNode("//ANALYSES"); 

       // Get all the ANALYSE nodes in parent node ANALYSES 
       var analysesNodes = analyses.SelectNodes("//ANALYSE"); 

       // Loop through the ANALYSE nodes 
       for (int j = 0; j < analysesNodes.Count; j++) 
       { 
        // Store them.. 
        ANALYSE tempresultaat = new ANALYSE(); 

        tempresultaat.AFKORTING = analysesNodes[j].ChildNodes[0].InnerText; 
        tempresultaat.WAARDE = analysesNodes[j].ChildNodes[1].InnerText; 
        tempresultaat.EENHEID = analysesNodes[j].ChildNodes[2].InnerText; 

        xmlanalyse.ANALYSES.Add(tempresultaat); 
       } 

       onderzoek.RESULTATEN.Add(xmlanalyse); 
      } 
     } 

У меня есть проблема с этим циклом является то, что он не провести различие между узлами INSTRUMENT. Результатом этого является то, что в первом цикле я получаю все значения из ANALYZE с первого узла INSTRUMENT, но также получаю значения из ANALYZE со второго узла INSTRUMENT. Это также происходит во втором цикле.

Как я могу решить эту проблему?

ответ

1

Вам необходимо указать текущий контекст (просто .) на ваших XPaths выражениях:

var instrumentNodes = resultaten.SelectNodes(".//INSTRUMENT"); 
var analyses = instrumentNodes[i].SelectSingleNode(".//ANALYSES"); 
var analysesNodes = analyses.SelectNodes(".//ANALYSE"); 

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

foreach (XmlElement instrument in xml.SelectNodes("//INSTRUMENT")) 
{ 
    Console.WriteLine(instrument.SelectSingleNode("INSTRUMENT_CODE").InnerText); 

    foreach (XmlElement analyse in instrument.SelectNodes("ANALYSES/ANALYSE")) 
    { 
     Console.WriteLine(analyse.SelectSingleNode("AFKORTING").InnerText); 
    } 
} 

Другое предложение состоит в том, чтобы избежать синтаксиса ChildNodes[n], так как ваш код будет разбит, если файл XML изменится. Рассмотрим вышеприведенный пример «AFKORTING».

Вы пытаетесь преобразовать XML-файл в бизнес-объекты? Вы пробовали deserialize?

Смежные вопросы