【问题标题】:xml attributes not being detected未检测到 xml 属性
【发布时间】:2014-12-29 22:46:54
【问题描述】:

我的 c# 应用程序遇到了一些问题。只能获取第一个节点的属性,无法获取后面节点的属性。

XML 就是这种格式..

<ALLPRODUCTS>
  <PRODUCT ITEM="1">
     <QUANTITY>5</QUANTITY>
  </PRODUCT>
  <PRODUCT ITEM="2">
     <QUANTITY>6</QUANTITY>
  </PRODUCT>....

应用程序将第一个产品编号设为 1,数量为 5……但之后它只给出数量并说项目编号为空。这是我使用的代码...

 while (reader.Read())
        {
            if (reader.Name.Equals("PRODUCT"))
            {
                String id;
                String qty;                

                try
                {

                    id = reader.GetAttribute("ITEM");
                    reader.ReadToFollowing("QUANTITY");
                    qty = reader.ReadInnerXml();

                    if (qty.Equals("0"))
                    {
                        oos++;
                    }
                    else
                    {
                        inStock++;
                    }

                    status.Refresh();
                    stockLevelList.Add(id, qty);

                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message, e.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            }

谁能指出为什么第一个产品之后的产品的 id 为空?

【问题讨论】:

  • 除非您的 XML 非常庞大(即大于 25 Mb),否则您最好使用 DOM 方法,例如 XmlDocument 和 SelectNodes 进行此类操作。
  • 我想你想做reader.MoveToNextAttribute()然后检查名字看是不是ITEM。如果是,那么您可以致电reader.Value 获取它。尽管如此,我可能只是将 XML 序列化与一些 POCO 一起使用,而不是与 XML Reader 对抗。它可以是相当适合开发的 PITA。
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • 感谢 cmets... TyCobb 我尝试了您的解决方案,但似乎没有什么不同。我让每次迭代都打印出“hasAttributes”评估,但在第一次之后他们都说错了。除了属性,一切似乎都在那里:/

标签: c# xml xmlreader


【解决方案1】:

您没有检查阅读器是否位于元素的开头。您的代码正在爆炸,因为它试图基于 PRODUCT 的结束元素进行处理。

在检查“PRODUCT”的 if 语句之后添加此检查。

if (reader.Name.Equals("PRODUCT"))
{
    if (!reader.IsStartElement())
        continue;

    // Your normal processing code here.
}

这就是使用XmlReader 有点痛苦的原因。它遍历每一个元素,这意味着你需要注意它可能在哪里。第一次通过,它位于起始元素。你处理了,一切都很好,但是它到达了&lt;/PRODUCT&gt; 元素,它仍然被命名为"PRODUCT",这就是它分崩离析的地方。

以下是基于您将reader 向前移动的代码的顺序。

  • reader.Read() 移动到第一个元素:ALLPRODUCTS
  • 不是您要查找的内容,所以再次 reader.Read() 并找到节点类型 Whitespace,因为没有内部文本。
  • reader.Read() 移至 PRODUCT
  • 您获得一个属性,然后告诉它读取到QUANTITY。 (请注意,您不能返回。订单很重要)
  • reader.Read() 移动到下一个元素 PRODUCT。这不是&lt;PRODUCT&gt;。是&lt;/PRODUCT&gt;
  • 您的代码现在再次开始上述大部分过程,但由于不在&lt;PRODUCT&gt; 上而失败

编辑:还要小心XmlReader。 XML 不一定要有效才能使XmlReader 工作到某个点。它只会在遇到问题时抛出错误,并且您可能已经处理了数百个节点。

【讨论】:

  • @FearghalConn 我通过将鼠标移到reader 上检查每个Read() 之后的值立即发现了问题。它说“EndElement”。调试器是你的朋友;)
猜你喜欢
  • 2021-01-26
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-09
相关资源
最近更新 更多