我有一个像这样的XML文件:
<Document>
<Tests Count="4">
<Test>
<Name>test with a</Name>
<Type>VI test</Type>
<Result>Pass</Result>
</Test>
<Test>
<Name>test plot</Name>
<Type>Curve test</Type>
<Result>Fail</Result>
</Test>
<Test>
<Name>test fixture</Name>
<Type>Leakage test</Type>
<Result>Pass</Result>
</Test>
<Test>
<Name>test fixture</Name>
<Type>Leakage test</Type>
</Test>
</Tests>
</Document>
我创建了一个类来包含每个“Test”:
class TestGroup
{
public string TestName { get; set; }
public string TestType { get; set; }
public string TestResult { get; set; }
}
由于我非常喜欢XML,目前我得到这样的数据(ztr是XmlDocument
):
public List<TestGroup> GetTestGroups()
{
List<TestGroup> TestNode = new List<TestGroup>();
string[] type_t = new string[GetTestsNumber()];
string[] name_t = new string[GetTestsNumber()];
string[] result_t = new string[GetTestsNumber()];
//name
string xpath = "/Document/Tests/Test";
int i = 0;
foreach (XmlElement Name in ztr.SelectNodes(xpath))
{
name_t[i] = Name.SelectSingleNode("Name").InnerText;
i++;
}
///////////
//result
xpath = "/Document/Tests/Test";
i = 0;
foreach (XmlElement Result in ztr.SelectNodes(xpath))
{
result_t[i] = Result.SelectSingleNode("Result").InnerText;
i++;
}
/////////////////
xpath = "/Document/Tests/Test";
i = 0;
foreach (XmlElement Type in ztr.SelectNodes(xpath))
{
type_t[i] = Type .SelectSingleNode("Type").InnerText;
i++;
}
int count = type_t.GetLength(0);
for (i = 0; i < count; i++)
{
LUTestGroup node = new LUTestGroup();
node.TestName = name_t[i];
node.TestType = type_t[i];
node.TestResult = result_t[i];
TestNode.Add(node);
}
return TestNode;
}
显然这种方式非常危险。它在xml时间内分开单独的时间,每次都向类中添加一个属性。另外,如果您在示例xml文件中注意到。最后一个Test
noet有一个Result
节点,所以当我输入不同的XML文件时,我写的代码有时会崩溃。
你能帮我吗?请写一个方法来安全地让所有可用于XML文件的测试填充List,如果其中任何一个没有节点,该方法不会崩溃?并且必须重要,在ONE GO中完成工作!
由于
答案 0 :(得分:4)
(正如评论中所述。)
LINQ to XML版本非常简单:
// Could use doc.Root.Element("Tests").Elements("Test") to be explicit
return doc.Descendants("Test")
.Select(x => new LUTestGroup {
TestName = (string) x.Element("Name"),
TestType = (string) x.Element("Type"),
TestResult = (string) x.Element("Result")
})
.ToList();
请注意,如果您为XElement
引用,则string
到XElement
的强制转换将返回null,因此在您的“泄漏测试”情况下,您最终会得到LUTestGroup
具有空TestResult
属性。
答案 1 :(得分:3)
在我看来,你正在努力做到这一点。让系统为你解析xml!您可以注释类以告诉它xml的样子:
[XmlRoot("Document")]
public class TestWrapper {
private readonly List<TestGroup> tests = new List<TestGroup>();
[XmlArray("Tests"), XmlArrayItem("Test")]
public List<TestGroup> Tests { get { return tests; } }
}
public class TestGroup {
[XmlElement("Name")] public string TestName { get; set; }
[XmlElement("Type")] public string TestType { get; set; }
[XmlElement("Result")] public string TestResult { get; set; }
}
然后:
TestWrapper doc;
using(var reader = XmlReader.Create(source))
{
var serializer = new XmlSerializer(typeof (TestWrapper));
doc = (TestWrapper) serializer.Deserialize(reader);
}
// et voila; loaded! prove it:
foreach(var item in doc.Tests)
{
Console.WriteLine("{0}: {1}, {2}",
item.TestName, item.TestType, item.TestResult);
}
你也可以使用XmlSerializer
创建 xml,使用相同的布局,虽然(相当多余的,IMO)/Document/Tests/@Count
很痛苦 - 我可以告诉你如何如果你真的需要,请解决这个问题。