【问题标题】:Summing XML attributes sometimes returns zero对 XML 属性求和有时会返回零
【发布时间】:2012-01-01 09:10:15
【问题描述】:

我正在尝试解析一个 NZB 文件(即 XML)并对字节属性求和。有时它工作得很好,有时它返回零,我不知道为什么。据我所知,NZB 文件具有相同的结构。

private Int32 processNZB(string sFilename)
{
    XDocument xFile = XDocument.Load(sFilename);

    Int32 sum = xFile.Descendants("segment").Sum(x => (int)x.Attribute("bytes"));

    sum = (int)(sum / 1024 / 1024); // bytes -> MB
    return sum;
}

源代码和示例文件可以在这里找到:http://jonathanslaven.com/.for/.stackoverflow/

这不起作用有明显的原因吗?有没有更好的方法来做到这一点?感谢您的帮助。

【问题讨论】:

  • 标题中不需要写C#。这就是标签的用途。

标签: c# xml .net-3.5 linq-to-xml


【解决方案1】:

也许 sum 的初始值小于 10242 个字节?当您执行整数除法时,结果将被截断,因此小于 10242 字节的任何内容都将返回零。

例如,example NZB file @ wikipedia 在运行您的算法时会给出 0。

编辑:

在检查“坏”文件(实际上,它是不符合规范的“好”文件)后,它不起作用的原因是根元素的默认命名空间是 "http://www.newzbin.com/DTD/2003/nzb",意思是任何子元素节点将继承此命名空间。

这意味着您的查询.Descendants("segment") 不返回任何节点。附加正确的命名空间可以解决问题。

下面展示了如何修改代码来读取这样的文件。

private int ProcessNzb(string sFilename)
{
    XDocument xDoc = XDocument.Load(sFilename);
    return xDoc
        .Descendants(xDoc.Root.Name.Namespace + "segment")
        .Sum(x => (int) x.Attribute("bytes")) / 1024 / 1024;
}

顺便说一句,我会避免发布暗示参与违禁品的文件。

【讨论】:

  • 感谢您的快速回复,成功了。这是我第一次玩弄 XML 文件。 (PS:没有违禁品,我订阅的频道上的所有电视节目)
【解决方案2】:

如果你改变它是否有效

Int32 sum = xFile.Descendants("segment").Sum(x => (int)x.Attribute("bytes"));

Int32 sum = xFile.Descendants("segment").Sum(x => int.Parse(x.Attribute("bytes").Value));

【讨论】:

  • XAttributeint 的显式转换运算符的作用与您的替代方法几乎相同。
【解决方案3】:

在使用整数除法除以 1024 时,总和是否可能小到可以舍入为 0?

一个例子:

int sum = 300; //300
int sumDividedOnce = sum/1024; // 0
int sumDividedTwice = sumDividedOnce/1024; // 0

【讨论】:

  • 感谢您的回复 - 不,如果我评论该行并返回字节而不是兆字节,那是一样的
猜你喜欢
  • 2019-04-02
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
  • 2012-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多