我有以下XML文件
<?xml version="1.0" ?>
<Persons>
<Person>
<Id>1</Id>
<Name>temp</Name>
<Qlid>1234</Qlid>
<Manager>3</Manager>
</Person>
<Person>
<Id>2</Id>
<Name>someone</Name>
<Qlid>5678</Qlid>
<Manager>1</Manager>
</Person>
</Persons>
Run Code Online (Sandbox Code Playgroud)
我试图使用以下c#函数阅读它
protected void readXmlFile()
{
FileStream fs = new FileStream("C:/Documents and Settings/me/Desktop/chart.xml",FileMode.Open);
XmlTextReader r = new XmlTextReader(fs);
//debug
StringWriter st = new StringWriter();
List<Person> persons = new List<Person>();
//Loop through persons in XML
while (r.Read())
{
if (r.NodeType == XmlNodeType.Element && r.Name == "Person")
{
Person newPerson = new Person();
while (r.NodeType != XmlNodeType.EndElement)
{
r.Read();
if (r.Name == "Id")
{
st.Write("67");
while (r.NodeType != XmlNodeType.EndElement)
{
r.Read();
if (r.NodeType == XmlNodeType.Text)
{
newPerson.Id = Int32.Parse(r.Value);
st.Write(r.Value);
}
}
}
r.Read();
if (r.Name == "Name")
{
while (r.NodeType != XmlNodeType.EndElement)
{
r.Read();
if (r.NodeType == XmlNodeType.Text)
{
newPerson.Name = (r.Value);
st.Write("23");
}
}
}
r.Read();
if (r.Name == "Qlid")
{
while (r.NodeType != XmlNodeType.EndElement)
{
r.Read();
if (r.NodeType == XmlNodeType.Text)
{
newPerson.Qlid = (r.Value);
st.Write(r.Value);
}
}
}
r.Read();
if (r.Name == "Manager")
{
while (r.NodeType != XmlNodeType.EndElement)
{
r.Read();
if (r.NodeType == XmlNodeType.Text)
{
newPerson.Manager = Int32.Parse(r.Value);
st.Write(r.Value);
}
}
}
//add to list
persons.Add(newPerson);
st.Write(90);
}
}
}
fs.Close();
Run Code Online (Sandbox Code Playgroud)
if(r.Name ="Id")和类似的ifs由于某种原因永远不会变为真,返回空人类
Rob*_*ine 10
除非你的XML非常大,并且不能一次性加载到内存中,否则我几乎肯定不会走这条路.
使用XmlReaderfor,over XmlDocument或Linq2Xml的麻烦是你缺少XPath或Linq的所有功能,它们的设计完全符合你在这里尝试做的事情:从xml中选择特定的节点.
或者,它看起来你只是将一些xml反序列化为dto,你的Person.这正是内置的xml序列化为您所做的.如果你愿意的话,你可以在你的dto上用一些属性实现这个目的.
但是,关于为什么这个具体不起作用:
检查一个Person元素,然后在寻找不是结束元素的东西时循环.我的猜测是你希望下一个节点成为Name元素.事实并非如此.你的下一个Read()给你一个空白节点.这会抛弃您对所期望元素的所有后续测试.这突出了您正在做的事情的关键问题:这种方法对于xml中的细微变化非常脆弱.每次你盲目地执行Read()时,你都假设你知道下一个节点是什么.如果它不是您所期望的,那么您的代码可能会失败,以至于在实际发生故障之前不容易发现.
是否有令人信服的理由不使用其他方法?我的直觉是,如果你这样做,你会省去很多麻烦!