【发布时间】:2011-05-22 05:19:56
【问题描述】:
无法弄清楚为什么我的 xml 更新在 IsolatedStorage 上失败,并且想知道是否有其他人遇到过类似的问题。
我正在尝试通过遍历所有特定节点并单独更新它们来更新文件。
由于某种原因,它中途失败,然后声明数据在根级别无效,并且无效数据在文件末尾???
代码如下:
我为每个练习调用 Update 方法:
foreach (var exercise in program.Exercises)
{
UpdateExercise(program, exercise, true);
}
其中使用静态属性并调用数据源的Update方法:
public void UpdateExercise(WorkoutProgram program, Exercise entity, bool isConversionUpdate)
{
ProgramDataSource.Update(program, entity, isConversionUpdate);
}
然后调用此方法并在此行的几个循环后失败:'root = XElement.Load(XmlReader.Create(fs));'
public void Update(WorkoutProgram program, Exercise exercise, bool isConversionUpdate)
{
SetupProgramSource(program);
XElement root;
if (!isConversionUpdate)
exercise.ChangeDate = DateTime.Now;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.FileExists(_exerciseFile))
{
throw new NotFoundException("The file does not exist!");
}
using (var fs = store.OpenFile(_exerciseFile, FileMode.Open, FileAccess.Read))
{
root = XElement.Load(XmlReader.Create(fs));
var element = root.Element("Exercises").Elements("Exercise").Where(e => e.Element("ID").Value.ToLower().Equals(exercise.ID.ToString().ToLower())).Single();
element.SetElementValue("Description", exercise.Description);
element.SetElementValue("Name", exercise.Name);
var exerciseChanges = element.Element("ExerciseChanges");
if (exercise is AnaerobicExercise)
{
var anaerobicExercise = exercise as AnaerobicExercise;
element.SetElementValue("Reps", anaerobicExercise.Repetitions);
element.SetElementValue("Sets", anaerobicExercise.Sets);
element.Element("Weight").SetElementValue("Amount", anaerobicExercise.Weight.Amount);
element.Element("Weight").SetElementValue("Measurement", anaerobicExercise.Weight.Measurement);
...
}
if (exercise is AerobicExercise)
{
var aerobicExercise = exercise as AerobicExercise;
element.SetElementValue("Distance", aerobicExercise.Distance);
element.Element("Duration").SetAttributeValue("hours", aerobicExercise.Duration.Hours);
element.Element("Duration").SetAttributeValue("minutes", aerobicExercise.Duration.Minutes);
element.Element("Duration").SetAttributeValue("seconds", aerobicExercise.Duration.Seconds);
element.SetElementValue("Measurement", aerobicExercise.Measurement);
if (!isConversionUpdate)
{
var exerciseChange = exercise.Changes.OfType<AerobicExerciseChange>().FirstOrDefault(ec => ec.ChangeDate.Date == exercise.ChangeDate.Date);
if (exerciseChange != null)
{
var changesElement = exerciseChanges.Elements("Changes").First(x => x.Attribute("id").Value.ToLower().Equals(exerciseChange.ID.ToString().ToLower()));
changesElement.SetAttributeValue("hours", aerobicExercise.Duration.Hours);
changesElement.SetAttributeValue("minutes", aerobicExercise.Duration.Minutes);
changesElement.SetAttributeValue("seconds", aerobicExercise.Duration.Seconds);
changesElement.SetAttributeValue("distance", aerobicExercise.Distance);
var change = exercise.Changes.OfType<AerobicExerciseChange>().First(ec => ec.ChangeDate.Date == exercise.ChangeDate.Date);
change.Duration = aerobicExercise.Duration;
change.Distance = aerobicExercise.Distance;
}
else
{
var changeDate = new XAttribute("changeDate", string.Format("{0:dd/MM/yyyy}", aerobicExercise.ChangeDate));
var typeAttribute = new XAttribute("type", "Aerobic");
var hoursAttribute = new XAttribute("hours", aerobicExercise.Duration.Hours);
var minutesAttribute = new XAttribute("minutes", aerobicExercise.Duration.Minutes);
var secondsAttribute = new XAttribute("seconds", aerobicExercise.Duration.Seconds);
var distanceAttribute = new XAttribute("distance", aerobicExercise.Distance);
var changesElement = new XElement("Changes");
exerciseChange = WorkoutManagerEntityFactory.GetEntityChange<AerobicExerciseChange>();
var idAttribute = new XAttribute("id", exerciseChange.ID.ToString());
changesElement.Add(idAttribute, typeAttribute, hoursAttribute, minutesAttribute, secondsAttribute, distanceAttribute, changeDate);
exerciseChanges.Add(changesElement);
exerciseChange.ChangeDate = aerobicExercise.ChangeDate;
exerciseChange.Distance = aerobicExercise.Distance;
exerciseChange.Duration = aerobicExercise.Duration;
aerobicExercise.Changes.Add(exerciseChange);
}
}
else
{
foreach (var aerobicExerciseChange in exercise.Changes.OfType<AerobicExerciseChange>())
{
var changesElement = exerciseChanges.Elements("Changes").First(x => x.Attribute("id").Value.ToLower().Equals(aerobicExerciseChange.ID.ToString().ToLower()));
changesElement.SetAttributeValue("hours", aerobicExercise.Duration.Hours);
changesElement.SetAttributeValue("minutes", aerobicExercise.Duration.Minutes);
changesElement.SetAttributeValue("seconds", aerobicExercise.Duration.Seconds);
changesElement.SetAttributeValue("distance", aerobicExercise.Distance);
var change = exercise.Changes.OfType<AerobicExerciseChange>().First(ec => ec.ID == aerobicExerciseChange.ID);
change.Duration = aerobicExercise.Duration;
change.Distance = aerobicExercise.Distance;
}
}
}
}
using (var fs = store.OpenFile(_exerciseFile, FileMode.Open, FileAccess.Write))
{
root.Save(fs);
}
}
}
XML(删除了大部分练习节点的简化版本):
<?xml version="1.0" encoding="utf-8"?>
<Program name="Strength Training">
<ID>2eec20d2-a278-11df-bc86-00138f82a706</ID>
<Duration hours="0" minutes="39" seconds="0" />
<Description>Main workout program for general all over fitness</Description>
<Exercises>
<Exercise exerciseType="Aerobic">
<ID>6E391E75-E75C-49CA-95FC-FEDF03D3ED1A</ID>
<Name>Treadmill Run</Name>
<Description>With a bar-bell on your back, feet shoulder width apart, back straight, knees slightly bent and in line with the feet, slowly go down and then back up. Squats develop power and strength.</Description>
<Distance>4</Distance>
<Duration hours="0" minutes="10" seconds="0" />
<Measurement>Kilometres</Measurement>
<ExerciseChanges>
<Changes id="291C3CCA-9997-4B4E-A1D5-75129DBB2638" type="Aerobic" hours="0" minutes="10" seconds="0" distance="4" changeDate="27/11/2010" />
</ExerciseChanges>
</Exercise>
<Exercise exerciseType="Anaerobic">
<ID>2eec20c5-a278-11df-bc86-00138f82a706</ID>
<Name>Squats</Name>
<Description>With a bar-bell on your back, feet shoulder width apart, back straight, knees slightly bent and in line with the feet, slowly go down and then back up. Squats develop power and strength.</Description>
<Reps>10</Reps>
<Weight>
<Amount>130</Amount>
<Measurement>Kilograms</Measurement>
</Weight>
<Sets>1</Sets>
<ExerciseChanges>
<Changes id="D20A177E-BC23-49B0-99CD-1F467590A996" type="Anaerobic" amount="130" sets="1" reps="10" changeDate="27/11/2010" />
</ExerciseChanges>
</Exercise>
<Exercise exerciseType="Anaerobic">
<ID>2eec20d1-a278-11df-bc86-00138f82a706</ID>
<Name>Abs</Name>
<Description>With a bar-bell on your back, feet shoulder width apart, back straight, knees slightly bent and in line with the feet, slowly go down and then back up. Squats develop power and strength.</Description>
<Reps>15</Reps>
<Weight>
<Amount>0</Amount>
<Measurement>Kilograms</Measurement>
</Weight>
<Sets>1</Sets>
<ExerciseChanges>
<Changes id="FFF2FF28-607F-465E-8BAC-B4F21E568253" type="Anaerobic" amount="0" sets="1" reps="15" changeDate="27/11/2010" />
</ExerciseChanges>
</Exercise>
</Exercises>
<ProgramChanges>
<Duration id="0BA96209-CF3C-4E85-8EB5-3BEE6A2DB118" hours="0" minutes="45" seconds="0" changeDate="27/11/2010" />
<Duration id="DAEEE9DF-A155-48AC-A5CE-09D738947C76" hours="0" minutes="39" seconds="0" changeDate="28/11/2010" />
</ProgramChanges>
</Program>
编码是没有BOM的UTF-8。
有人见过这个吗?
感谢所有想法(即使有人说我的代码很垃圾,需要重构)。
编辑:
添加问题:InvalidOperationException - 缺少父对象:
private static XElement GetExerciseElement(Exercise entity)
{
var exerciseElement = new XElement("Exercise");
if (entity is AnaerobicExercise)
{
var anaerobicExercise = entity as AnaerobicExercise;
var exerciseTypeAttribute = new XAttribute("exerciseType", "Anaerobic");
var amountElement = new XElement("Amount", anaerobicExercise.Weight.Amount);
var measurementElement = new XElement("Measurement", anaerobicExercise.Weight.Measurement);
var weightElement = new XElement("Weight");
var nameElement = new XElement("Name", anaerobicExercise.Name);
var descriptionElement = new XElement("Description", anaerobicExercise.Description);
var repsElement = new XElement("Reps", anaerobicExercise.Repetitions);
var setsElement = new XElement("Sets", anaerobicExercise.Sets);
var idElement = new XElement("ID", anaerobicExercise.ID);
var exerciseChangesElement = new XElement("ExerciseChanges");
weightElement.Add(amountElement, measurementElement);
var exerciseChange = new AnaerobicExerciseChange
{
ChangeDate = entity.ChangeDate,
Amount = anaerobicExercise.Weight.Amount,
Sets = anaerobicExercise.Sets,
Repetitions = anaerobicExercise.Repetitions
};
entity.Changes.Add(exerciseChange);
exerciseElement.Add(exerciseTypeAttribute, idElement, nameElement, descriptionElement, repsElement, weightElement, setsElement);
exerciseChangesElement.ReplaceWith(GetExerciseChanges(entity, exerciseElement, exerciseChange));
exerciseElement.Add(exerciseChangesElement);
}
尤其是这一行:
exerciseChangesElement.ReplaceWith(GetExerciseChanges(entity, exerciseElement, exerciseChange));
【问题讨论】:
-
是否有生成的 xml 示例片段?
-
我的错!我将添加 XML 文件。它应该只更新元素和属性值。
标签: c# xml windows-phone-7 linq-to-xml