【发布时间】:2015-05-27 16:08:25
【问题描述】:
我正在尝试基于从我的计算机本地读取的文件使用 XDocument 和 LINQ 构建 Xml 文件。 这似乎很容易(而且确实如此),直到我想处理特定的事情。
所以,我希望我的代码同时支持这两种格式
<FailReport>
<SystemDescription>
<SystemID>system1</SystemID>
<ReportDate>DATE</ReportDate>
<SpecFile>file1</SpecFile>
<UUT>unit1</UUT>
</SystemDescription>
<FailDescription>
<Test1>tst1</Test1>
<Test2>tst2</Test2>
<TestType>typ1</TestType>
<Component>cmp1</Component>
<LowerLimit>llimit</LowerLimit>
<UpperLimit>ulimit</UpperLimit>
<MeasuredValue>value</MeasuredValue>
</FailDescription>
</FailReport>
还有这种格式
<FailReport>
<SystemDescription>
<SystemID>system1</SystemID>
<ReportDate>DATE</ReportDate>
<SpecFile>file1</SpecFile>
<UUT>unit1</UUT>
</SystemDescription>
<FailDescription>
<Test1>tst1</Test1>
<Test2>tst2</Test2>
<TestType>typ1</TestType>
<Component>cmp1</Component>
<LowerLimit>llimit</LowerLimit>
<UpperLimit>ulimit</UpperLimit>
<MeasuredValue>value</MeasuredValue>
</FailDescription>
<FailDescription>
<Test1>tst3</Test1>
<Test2>tst4</Test2>
<TestType>typ2</TestType>
<Component>cmp2</Component>
<LowerLimit>llimit3</LowerLimit>
<UpperLimit>ulimit4</UpperLimit>
<MeasuredValue>value1</MeasuredValue>
</FailDescription>
</FailReport>
我有一个函数可以接收这样的参数:
public void newFail(string Tst1, string Tst2, string TestType, string Component, string LowerLimit, string UpperLimit, string MeasuredValue, string SystemID, string ReportDate, string SpecFile, string UUT)
在这个函数中我需要做几件事:
- 如果该位置不存在 Xml,我需要创建并填充它;
- 如果存在,则加载文件并进行编辑;
- 如果 Xml 文件中的某处已存在类似“May7,2014 18:44”的条目,则应用第二种格式(保留“标题”即“SystemDescription”,但添加第二个/第三个/wtv“FailDescription”具有“Test1”、“Test2”等不同参数的块。
- 如果不存在,则使用第一种格式并创建一个“全新块”。
这是我的自动取款机代码:
void newFail(string Tst1, string Tst2, string TestType, string Component, string LowerLimit, string UpperLimit, string MeasuredValue, string SystemID, string ReportDate, string SpecFile, string UUT)
{
if (doesElementExist("FailReport", "SystemDescription", "ReportDate", ReportDate)) //If an element with the same Report Date exists, add it to the same parent
{
ictLog.Element("FailReport").Elements("SystemDescription").Last(c => (string)c.Element("ReportDate").Value == ReportDate).Add(new XElement("FailDescription",
new XElement("Tst1", Tst1),
new XElement("Tst2", Tst2),
new XElement("TestType", TestType),
new XElement("Component", Component),
new XElement("LowerLimit", LowerLimit),
new XElement("UpperLimit", UpperLimit),
new XElement("MeasuredValue", MeasuredValue)));
}
else
{ //Otherwise add a new Parent
if (!firstEntry)
{
ictLog.Element("FailReport").Add(new XElement("FailReport",
new XElement("SystemDescription",
new XElement("SystemID", SystemID),
new XElement("ReportDate", ReportDate),
new XElement("SpecFile", SpecFile),
new XElement("UUT", UUT)),
new XElement("FailDescription",
new XElement("Tst1", Tst1),
new XElement("Tst2", Tst2),
new XElement("TestType", TestType),
new XElement("Component", Component),
new XElement("LowerLimit", LowerLimit),
new XElement("UpperLimit", UpperLimit),
new XElement("MeasuredValue", MeasuredValue))));
}
else
{
firstEntry = false;
ictLog = new XDocument(new XElement("FailReport",
new XElement("SystemDescription",
new XElement("SystemID", SystemID),
new XElement("ReportDate", ReportDate),
new XElement("SpecFile", SpecFile),
new XElement("UUT", UUT)),
new XElement("FailDescription",
new XElement("Tst1", Tst1),
new XElement("Tst2", Tst2),
new XElement("TestType", TestType),
new XElement("Component", Component),
new XElement("LowerLimit", LowerLimit),
new XElement("UpperLimit", UpperLimit),
new XElement("MeasuredValue", MeasuredValue))));
}
}
}
而函数“doesElementExist”的代码如下:
public bool doesElementExist(string rootName, string parentName,string childName, string nodeValue)
{
if (!firstEntry)
{
bool value = ictLog.Elements(rootName).Elements(parentName) //Get any item where the child value is the same as the specificed one (for some reason it works on reverse, returns false if found)
.Elements(childName)
.Any(x => x.Value == nodeValue);
return value;
}
else
return false;
}
如果我在具有 .xml 扩展名的位置上找不到任何文件,我会设置标志第一个条目。
我的问题是,生成的 XML 文件第一次按应有的方式分组(当日期参数与 xml 中已有的相同时使用第二种格式)但重复每个条目。如果我使用不同的标头再次调用该函数,它会使用第一种格式正确创建,但即使条目已经存在(不应用第二种格式)也不会分组。请注意,我有相同的日期,但它没有按应有的分组。 示例输出:
<FailReport>
<SystemDescription>
<SystemID>ICTT_0030</SystemID>
<ReportDate>May7,2014 18:44</ReportDate>
<SpecFile>xptofile.c</SpecFile>
<UUT>123</UUT>
<FailDescription>
<Tst1>tsts</Tst1>
<Tst2>tsts1</Tst2>
<TestType>type2</TestType>
<Component>cTst1</Component>
<LowerLimit>0.400</LowerLimit>
<UpperLimit>0.800</UpperLimit>
<MeasuredValue>O_RngV</MeasuredValue>
</FailDescription>
<FailDescription>
<Tst1>tsts</Tst1>
<Tst2>tsts1</Tst2>
<TestType>type2</TestType>
<Component>cTst1</Component>
<LowerLimit>0.900</LowerLimit>
<UpperLimit>0.700</UpperLimit>
<MeasuredValue>0.91</MeasuredValue>
</FailDescription>
<FailReport>
<SystemDescription>
<SystemID>ICTT_0030</SystemID>
<ReportDate>May7,2014 18:44</ReportDate>
<SpecFile>xptofile.c</SpecFile>
<UUT>123</UUT>
<FailDescription>
<Tst1>tsts</Tst1>
<Tst2>tsts1</Tst2>
<TestType>type2</TestType>
<Component>cTst1</Component>
<LowerLimit>0.400</LowerLimit>
<UpperLimit>0.800</UpperLimit>
<MeasuredValue>O_RngV</MeasuredValue>
</FailDescription>
<FailDescription>
<Tst1>tsts</Tst1>
<Tst2>tsts1</Tst2>
<TestType>type2</TestType>
<Component>cTst1</Component>
<LowerLimit>0.900</LowerLimit>
<UpperLimit>0.700</UpperLimit>
<MeasuredValue>0.91</MeasuredValue>
</FailDescription>
<SystemDescription>
<SystemID>lalalala</SystemID>
<ReportDate>May21,2014 11:59</ReportDate>
<SpecFile>filefile</SpecFile>
<UUT>111</UUT>
</SystemDescription>
<FailDescription>
<Tst1>TP1300-T[201]</Tst1>
<Tst2>Tst2002-G[1]</Tst2>
<TestType>Res</TestType>
<Component>R1301</Component>
<LowerLimit>9.9000K</LowerLimit>
<UpperLimit>13.000K</UpperLimit>
<MeasuredValue>13.089K</MeasuredValue>
</FailDescription>
</FailReport>
<FailReport>
<SystemDescription>
<SystemID>lalalala</SystemID>
<ReportDate>May21,2014 11:59</ReportDate>
<SpecFile>filefile</SpecFile>
<UUT>111</UUT>
</SystemDescription>
<FailDescription>
<Tst1>tsts11111</Tst1>
<Tst2>tssa9</Tst2>
<TestType>Res</TestType>
<Component>kkk</Component>
<LowerLimit>9.9000K</LowerLimit>
<UpperLimit>13.000K</UpperLimit>
<MeasuredValue>13.089K</MeasuredValue>
</FailDescription>
抱歉,这篇文章太长了,但我尽量详细地记录下来。
【问题讨论】:
-
注意:第二种格式可以有两个以上的条目。
-
我的解决方案使用 List
可以处理单个对象或多个对象。
标签: c# xml linq linq-to-xml element