什么是XmlNodeType.Document? XmlNodeType.Element和XmlNodeType.Document之间的区别

时间:2009-10-11 23:30:36

标签: c# xml xmlreader

我正在使用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但我想以这种方式解决,不要问我为什么,因为我想学习解决这些问题的各种方法。

提前致谢。

...此致

2 个答案:

答案 0 :(得分:2)

你提出的答案至少有五种不同的方式存在缺陷。

  1. 它肯定不是“通用解决方案”,因为您的代码现在完全依赖于XML中的信息 - 如果处理的XML文档包含您添加的flag属性,则您的方法只能正确计算元素

  2. 标记属性是不必要的。每当XmlReader在它正在读取的流的开头开始时,它读取的第一个元素总是将成为顶级元素。它不可能是其他任何东西。您可以使用标记来跟踪是否已经读取了顶级元素,而不是在文档中添加属性来标识顶级元素。或者,你可以从总数中减去1。

  3. 即使你 需要flag属性,你做错了。您正在使用MoveToFirstAttribute来查找它。如果元素上有多个重点,该怎么办?如果代码找到的值为True的第一个属性不是Root,该怎么办?如果其中一个子元素具有该值的属性,该怎么办?如果您要为此目的使用属性,则应该在非常至少按名称搜索它。

  4. 此代码不会计算顶级元素的所有元素,它会计算所有后代元素。阅读器按文档顺序从节点移动到节点。如果元素节点具有子节点,则该子节点是Read()读取的下一个节点。 XmlReader有一些方法可以用来读取整个元素及其所有内容,但你没有使用它们。

  5. 条件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();
        }

    }