【问题标题】:C# XmlTextReader not reading all elements and attributesC# XmlTextReader 不读取所有元素和属性
【发布时间】:2012-06-16 22:23:34
【问题描述】:

我正在尝试从 xml 文件中读取数据并将其显示在文本框中,但它仅显示最后一个元素/属性,在本例中为“耐力”。这是我的xml文件

<?xml version="1.0" encoding="utf-8"?>
<Character>
  <Name
   Name="Test" />
   <Age
   Age="19" />
  <Class
  Class="Necromancer" />
  <Strength
  Strength="1" />
  <Dexterity
  Dexterity="2" />
  <Intelligence
  Intelligence="3" />
  <Speed
  Speed="4" />
  <Endurance
  Endurance="5" />
</Character>

我的读者代码如下

XmlTextReader reader = new XmlTextReader(openFileDialog1.FileName);
while (reader.Read())
{
   if (reader.HasAttributes)
   {
     for (int i = 0; i < reader.AttributeCount; i++)
     {
       reader.MoveToAttribute(i);
       switch (reader.Name)
       {
         case "Name":
             DisplayBox.Text = "Name: " + reader.Value + "\n";
             break;
         case "Age":
             DisplayBox.Text = "Age: " + reader.Value + "\n";
             break;
         case "Class":
             DisplayBox.Text = "Class: " + reader.Value + "\n";
             break;
         case "Strength":
             DisplayBox.Text = "Strength: " + reader.Value + "\n";
             break;
         case "Dexterity":
             DisplayBox.Text = "Dexterity: " + reader.Value + "\n";
             break;
         case "Intelligence":
             DisplayBox.Text = "Intelligence: " + reader.Value + "\n";
             break;
         case "Speed":
             DisplayBox.Text = "Speed: " + reader.Value + "\n";
             break;
         case "Endurance":
             DisplayBox.Text = "Endurance: " + reader.Value + "\n";
             break;
         default:
             break;
       }
     }
         reader.MoveToElement();
  }
}

所以每当我点击按钮显示数据时,文本框中唯一显示的是 Endurance: 5

【问题讨论】:

    标签: c# xml winforms


    【解决方案1】:

    看来你需要更换

    DisplayBox.Text =
    

    DisplayBox.Text +=
    

    此外,所有切换条件都非常相似。所以你可以使用以下内容:

    string[] supportedAttributes = new []{"Name", "Age", "Class", "Strength", "Dexterity", "Intelligence", "Speed", "Endurance"};
    while (reader.Read())
    {
       if (reader.HasAttributes)
       {
         for (int i = 0; i < reader.AttributeCount; i++)
         {
           reader.MoveToAttribute(i);
           if(supportedAttributes.Any(a=>a == reader.Name))
               DisplayBox.Text += string.Format("{0}: {1} \n", reader.Name, reader.Value);
         }
         reader.MoveToElement();
      }
    }
    

    【讨论】:

      【解决方案2】:

      我没有直接回答您的问题,而是提供了另一种编写代码的方法。

      switch 语句,特别是重复自身,并且可以删除重复。

      还使用switch 语句将您的代码锁定为特定值。您无法动态更改要使用的属性名称列表 - 例如,可能用于不同的语言。

      这是我的代码:

      var xd = XDocument.Load(openFileDialog1.FileName);
      
      var query =
          from xe in xd.Descendants()
          from xa in xe.Attributes()
          let r = map(xa.Name.ToString(), xa.Value)
          where r != null
          select r;
      
      DisplayBox.Text = String.Join("", query);
      

      现在唯一缺少的是map 函数的定义。这是代码变得有点前卫的地方。

      首先从您要查找的名称开始:

      var names = new []
      {
          "Name", "Age", "Class",
          "Strength", "Dexterity", "Intelligence",
          "Speed", "Endurance", 
      };
      

      现在我们只需要定义几个负责映射的变量:

      var nameMap =
          names
              .ToDictionary(
                  n => n,
                  n => (Func<string, string>)
                      (t => String.Format("{0}: {1}\n", n, t)));
      
      Func<string, string, string> map =
          (n, v) =>
              nameMap.ContainsKey(n) ? nameMap[n](v) : null;
      

      这有点棘手,但它很好地将名称列表与最终查询区分开来以获取您的数据,并让您的代码更清晰地处理需要维护的部分。

      【讨论】:

        【解决方案3】:

        而不是

            DisplayBox.Text = 
        

        你应该像这样使用

           DisplayBox.Text += 
        

        它应该做所要求的。

        【讨论】:

          【解决方案4】:

          目前您正在遍历所有节点。

          最终循环在最终节点处停止。那不过是耐力节点。

          所以你会看到结果是耐力。

          您需要检查特定条件,如果满足,则需要退出循环。

          或者

          如果您想在文本框中显示所有值,请遵循 @Kostya@Furqan 的答案。

          【讨论】:

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