我正在使用XmlReader来读取XML文件,我想在Document Element下面计算XML Element,因为我知道它应该是根元素。
XML
<?xml version="1.0" encoding="utf-8"?>
<NewsLetters>
<EMail Date="10/10/2009">hello@hello.com</EMail>
<EMail Date="10/10/2009">hello@hello.com</EMail>
<EMail Date="10/10/2009">hello@hello.com</EMail>
<EMail Date="10/10/2009">hello@hello.com</EMail>
</NewsLetters>
C#代码:
public static string TotalMemberCount()
{
XmlTextReader reader = new XmlTextReader(HttpContext.Current.Server.MapPath("~/Newsletter/NewsLetter.xml"));
int totalCount = 0;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.NodeType != XmlNodeType.Document)
totalCount++;
}
return totalCount.ToString();
}
通常我期待4条记录,但它会返回5条,因为它也会计算根元素。我该怎么办?其实我知道如何解决使用XDocument,XElement和LINQ但我想以这种方式解决,不要问我为什么,因为我想学习解决这些问题的各种方法。
提前致谢。
...此致
答案 0 :(得分:2)
你提出的答案至少有五种不同的方式存在缺陷。
它肯定不是“通用解决方案”,因为您的代码现在完全依赖于XML中的信息 - 如果处理的XML文档包含您添加的flag属性,则您的方法只能正确计算元素
标记属性是不必要的。每当XmlReader
在它正在读取的流的开头开始时,它读取的第一个元素总是将成为顶级元素。它不可能是其他任何东西。您可以使用标记来跟踪是否已经读取了顶级元素,而不是在文档中添加属性来标识顶级元素。或者,你可以从总数中减去1。
即使你 需要flag属性,你做错了。您正在使用MoveToFirstAttribute
来查找它。如果元素上有多个重点,该怎么办?如果代码找到的值为True
的第一个属性不是Root
,该怎么办?如果其中一个子元素具有该值的属性,该怎么办?如果您要为此目的使用属性,则应该在非常至少按名称搜索它。
此代码不会计算顶级元素的所有子元素,它会计算所有后代元素。阅读器按文档顺序从节点移动到节点。如果元素节点具有子节点,则该子节点是Read()
读取的下一个节点。 XmlReader
有一些方法可以用来读取整个元素及其所有内容,但你没有使用它们。
条件reader.NodeType != XmlNodeType.XmlDeclaration && reader.NodeType == XmlNodeType.Element
是多余的:如果节点是元素,则节点不可能是XML声明。
答案 1 :(得分:0)
无论如何,我找到了自己的解决方案,我想要的是找到一个通用的解决方案,所以我提出了这样的解决方案:
<强> XML 强>
<?xml version="1.0" encoding="utf-8"?>
<NewsLetters Root="True">
<EMail Date="10/10/2009">hello@hello.com</EMail>
<EMail Date="10/10/2009">hello@hello.com</EMail>
<EMail Date="10/10/2009">hello@hello.com</EMail>
<EMail Date="10/10/2009">hello@hello.com</EMail>
</NewsLetters>
<强> C#强>
public static string TotalMemberCount()
{
int totalCount = 0;
using (XmlTextReader reader = new XmlTextReader(HttpContext.Current.Server.MapPath("~/Newsletter/NewsLetter.xml")))
{
while (reader.Read())
{
if (reader.NodeType != XmlNodeType.XmlDeclaration && reader.NodeType == XmlNodeType.Element)
{
if (reader.MoveToFirstAttribute())
{
if (reader.Value == "True")
//gotcha, I don't want this,this is root element
continue;
}
totalCount++;
}
}
return totalCount.ToString();
}
}