2015-12-10 8 views
0

Пожалуйста, помогите мне исправить фрагмент кода, который приводит к этому выходу xml.XML XElement и петли

Элементы, называемые «Частота» и «Тип ScheduleType», все застревают под первым элементом расписания. Как это исправить?

Я читаю данные из файла типа CSV, а затем основываясь на позиции и значении, я добавляю соответствующие данные (или преобразованные значения) в соответствующие значения XML.

Вы увидите, что я использую предлагаемый метод, где это возможно, но поскольку мне нужно использовать дополнительный оператор CASE, я застреваю, поэтому я возвращаюсь к использованию инструкции LAST, чтобы попытаться найти правильный элемент для продолжения.

<Schedules> 
    <Schedule Number="1"> 
     <ScheduleName>Cumulative</ScheduleName> 
     <BackupType>Cinc</BackupType> 
     <Multiplexing>4</Multiplexing> 
     <RetentionLevel>infinite</RetentionLevel> 
     <ResidenceIsSLP>No</ResidenceIsSLP> 
     <MultipleCopies>No</MultipleCopies> 
     <ScheduleType /> 
     <Frequency> 
     <Count>5</Count> 
     <Unit>Days</Unit> 
     <Count>2</Count> 
     <Unit>Weeks</Unit> 
     <Count>1</Count> 
     <Unit>Days</Unit> 
     </Frequency> 
     <ScheduleType /> 
     <Frequency /> 
     <ScheduleType /> 
     <Frequency /> 
    </Schedule> 
    <Schedule Number="2"> 
     <ScheduleName>Full</ScheduleName> 
     <BackupType>Full</BackupType> 
     <Multiplexing>4</Multiplexing> 
     <RetentionLevel>infinite</RetentionLevel> 
     <ResidenceIsSLP>No</ResidenceIsSLP> 
     <MultipleCopies>No</MultipleCopies> 
    </Schedule> 
    <Schedule Number="3"> 
     <ScheduleName>Differential</ScheduleName> 
     <BackupType>Diff</BackupType> 
     <Multiplexing>4</Multiplexing> 
     <RetentionLevel>2 weeks</RetentionLevel> 
     <ResidenceIsSLP>No</ResidenceIsSLP> 
     <MultipleCopies>No</MultipleCopies> 
    </Schedule> 
    </Schedules> 

public XDocument PolicyAttributesSection() 
{ 
    XDocument policies = XDocument.Load("C:\\Output Files\\testnbu.xml"); 

    policies.Element("NBUConfig").Add(new XElement("Policies")); 
    using (TextFieldParser policy = new TextFieldParser("C:\\Input Files\\RAM\\bppllist.txt")) 
    { 
     string[] ignoreLines1 = { "NAMES", "KEY", "RCMD", "BCMD", "FOE", "SHAREGROUP", "APPLICATIONDEFINED", "SCHEDFOE" }; 
     policy.TextFieldType = FieldType.Delimited; 
     policy.Delimiters = new string[] { " ", ",", ";" }; 
     policy.HasFieldsEnclosedInQuotes = true; 
     policy.CommentTokens = ignoreLines1; 
     policy.TrimWhiteSpace = true; 

     string[] policyprops; 
     int schedulenumber; 

     while (!policy.EndOfData) 
     { 

      schedulenumber = 0; 
      var pl = policies.Element("NBUConfig").Element("Policies").Elements("Policy"); 
      policyprops = policy.ReadFields(); 
      switch (policyprops[0]) 
      { 
      case "SCHED": 
        schedulenumber++; 
        int scheduletypenumber; 
        bool schedparsed = int.TryParse((policyprops[2]), out scheduletypenumber); 
        string scheduletypename = ScheduleType_Lookup[(scheduletypenumber)]; 
        int retlevel; 
        bool retparsed = int.TryParse((policyprops[5]), out retlevel); 
        string retentionperiod = (Retention_Lookup[(retlevel)]).ToString(); 
        int isslp; 
        bool isslpparsed = int.TryParse((policyprops[17]), out isslp); 
        int copynumber; 
        bool copynumberparsed = int.TryParse((policyprops[12]), out copynumber); 
        if (copynumber > 0) 
        { 
         copynumber = 1; 
        } 
        pl.Last().Element("Schedules").Add(new XElement(("Schedule"), new XAttribute("Number", (schedulenumber)), 
        (new XElement("ScheduleName", policyprops[1])), 
        (new XElement("BackupType", (scheduletypename))), 
        (new XElement("Multiplexing", policyprops[3])), 
        (new XElement("RetentionLevel", (retentionperiod))), 
        (new XElement("ResidenceIsSLP", (yesno_lookup[(isslp)]))), 
        (new XElement("MultipleCopies", (yesno_lookup[(copynumber)]))))); 
        pl.Last().Element("Schedules").Element("Schedule").Add(new XElement(("ScheduleType"))); 
        switch (policyprops[11]) 
        { 
         case "1": 
          pl.Last().Element("Schedules").Element("Schedule").Add(new XElement("Calendar", "Enabled")); 
          pl.Last().Element("Schedules").Element("Schedule").Add 
        (new XElement("CalendarRetries", "Disabled")); 
          break; 
         case "2": 
          pl.Last().Element("Schedules").Element("Schedule").Add 
        (new XElement("Calendar", "Enabled")); 
          pl.Last().Element("Schedules").Element("Schedule").Add 
        (new XElement("CalendarRetries", "Enabled")); 
          break; 
         case "0": 
          int freqseconds; 
          bool startparsed = int.TryParse((policyprops[4]), out freqseconds); 
          var freq = frequency(freqseconds); 
          pl.Last().Element("Schedules").Element("Schedule").Add 
        (new XElement("Frequency")); 
          int count = freq.Item1; 
          string unit = freq.Item2; 
          pl.Last().Element("Schedules").Element("Schedule").Element("Frequency").Add 
        (new XElement("Count", (count).ToString())); 
          pl.Last().Element("Schedules").Element("Schedule").Element("Frequency").Add 
        (new XElement("Unit", (unit))); 
          break; 
        } 
        break; 
      } 
     } 
     policies.Save("C:\\Output Files\\testnbu.xml"); 
     return policies; 
+0

Первое, что нужно сделать: сделать свой код * намного проще, объявив переменную, содержащую ссылку на элемент «Политики». Затем, * внутри * цикла, объявите переменную, ссылаясь на элемент 'Policy', который вы добавляете. Я бы посоветовал вам сделать это и изменить свой вопрос, чтобы сделать вас намного проще помочь вам. –

+0

Ок, спасибо, я все еще учусь. Цените свою помощь. Я сделаю это и отправлю. –

+0

Даже при изменении вы все равно используете 'pol.Last' 6 раз ... вместо ссылки на элемент' Policy', который вы сейчас создаете. У вас также есть опечатки в «Schudule» вместо «Schedule». –

ответ

3

Это утверждение является проблема:

test.Element("NBUConfig") 
    .Element("Policies") 
    .Elements("Policy").Last() 
    .Elements("Schedules").Last() 
    .Element("Schedule") 
    .Add(new XElement(("SchedulesStuff"), (scount))); 

Вы добавления SchedulesStuff к первому Schedule элемента в течение последнего Schedules элемента ... вместо того, чтобы добавить его в последнегоSchedule элемента в пределах толькоSchedules элемент.

Весь этот код был бы намного, намного проще - и менее подвержен ошибкам - если бы у вас был гораздо менее повторяющийся код. Поэтому рассмотрим вместо этого:

var policies = new XElement("Policies"); 
var test = new XDocument(new XElement("NBUConfig", policies)); 

// Hint: for loops are more idiomatic than while loops here 
for (int pcount = 0; pcount < 3; pcount++) 
{ 
    var schedules = new XElement("Schedules"); 
    for (int scount = 0; scount < 3; scount++) 
    { 
     schedules.Add(new XElement("Schedule", 
      new XAttribute("Number", scount), 
      new XElement("ScheduleStuff", scount)); 
    } 

    policies.Add(new XElement("Policy", 
     new XElement("PolicyName", pcount), 
     new XElement("General"), 
     new XElement("Clients"), 
     new XElement("IncludeList"), 
     schedules));   
} 
+0

Спасибо, Джон. Причина, по которой я использую такой длинный метод, - это то, что я должен читать и обрабатывать данные из входного файла и добавлять дополнительные элементы, прежде чем переходить к следующим основным разделам, таким как Общие, Клиенты, IncludeLists и т. Д. Я, вероятно, это по-идиотски, но у меня есть 1 месяц опыта. Поскольку я сказал, что это не настоящий код, я просто использовал цикл while для имитации. Я починю по вашей предыдущей рекомендации, а затем опубликую немного. Возможно, это прояснит проблему. –

+0

@ RiaanBadenhorst: Ну нет, нет необходимости делать это на * этом * вопросе, потому что это не связано с вопросом. Но общий принцип избежания всех этих вызовов 'Element()' по-прежнему применяется. Вы можете создать элемент «General» отдельно, затем элемент «Клиенты» и т. Д. И по-прежнему использовать локальные переменные для ссылки на эти элементы, как и у меня с «расписаниями». –

+0

Привет, Джон, я думаю, я попробовал нечто похожее на то, что было сегодня. Единственное, что я заметил, это когда я использовал .Add, что я создаю совершенно новый элемент, он не просто добавляет другой экземпляр Schedules, например. В любом случае, чтобы вставить вместо Add? –