【问题标题】:What's XmlNodeType.Document ? Difference between XmlNodeType.Element and XmlNodeType.Document什么是 XmlNodeType.Document ? XmlNodeType.Element 和 XmlNodeType.Document 之间的区别
【发布时间】:2009-10-11 23:30:36
【问题描述】:

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

提前致谢。

真诚的......

【问题讨论】:

  • 没有答案?令人难过...

标签: c# xml xmlreader


【解决方案1】:

您提出的答案至少在五种不同方面存在缺陷。

  1. 这当然不是“通用解决方案”,因为您的代码现在完全依赖于 XML 中的信息 - 只有当它正在处理的 XML 文档包含您添加的标志属性时,您的方法才能正确计算元素.

  2. 标志属性是不必要的。任何时候XmlReader 从它正在读取的流的开头开始,它读取的第一个元素总是 将成为顶级元素。不可能是别的。无需在文档中添加属性来标识顶级元素,您只需使用标志来跟踪您是否已经阅读了顶级元素。或者见鬼,你可以从总数中减去 1。

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

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

  5. 条件reader.NodeType != XmlNodeType.XmlDeclaration &amp;&amp; reader.NodeType == XmlNodeType.Element 是多余的:如果一个节点是一个元素,它就不可能是一个XML 声明。

【讨论】:

    【解决方案2】:

    无论如何,我找到了自己的解决方案,我想要实现的是找到一个通用的解决方案,所以我想出了这样一个解决方案:

    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();
            }
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      相关资源
      最近更新 更多