1

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

提前致谢。

真挚地....

4

2 回答 2

2

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

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

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

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

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

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

于 2009-10-12T07:57:38.443 回答
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();
        }

    }
于 2009-10-12T00:13:58.777 回答