使用XmlReader读取属性值

25

我有一个XML文件,我想从 这里 读取,并且有以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace XML
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlTextReader textReader = new XmlTextReader("secLendingXML.cfm.xml");
            while (textReader.Read())
            {
                switch (textReader.NodeType)
                {
                    case XmlNodeType.Element:
                        Console.WriteLine(textReader.Name);
                        Console.WriteLine(textReader.Value);
                        break;
                    case XmlNodeType.Text:
                        Console.WriteLine(textReader.Value);
                        break;
                    case XmlNodeType.XmlDeclaration:
                    case XmlNodeType.ProcessingInstruction:
                        Console.WriteLine(textReader.Name + " " + textReader.Value);
                        break;
                    case XmlNodeType.Comment:
                        Console.WriteLine(textReader.Value);
                        break;
                    case XmlNodeType.EndElement:
                        break;
                }
            }
            Console.ReadLine();
        }
    }
}

代码在读取节点并返回名称方面运行正常。但问题在于我还尝试检索节点内的数据。换句话说,当它读取测试部分后的第一个部分时,它将读取:

slnc:DataSet
slnc:Group
slnc:Section
slnc:ActualAvailableToBorrow
*** here ***
slnc:oustandingLoans

我希望文本阅读器能够读取节点中如confidentiality="F"currency="USD"等数值,但它直接跳到了下一个部分而没有读取这些数值!

<slnc:actualAvailableToBorrow xmlns:slnc="http://www.newyorkfed.org/xml/schemas/SecLending" 
      confidentiality="F" currency="USD" decimals="0" method="AA" 
      multiplier="5" securityLendingType="AA" status="A" value="1474"/>

我该如何让TextReader读取属性值?最好能够打印出"value"为"currency"的属性及其对应的值"F"。

2个回答

58

获取单个指定名称的属性

使用XmlReader.GetAttribute (MSDN)

case XmlNodeType.Element:
  Console.WriteLine(textReader.Name);
  Console.WriteLine(textReader.Value);
  Console.WriteLine(textReader.GetAttribute("currency"));

这个函数的一个不错特性是:如果属性未定义,它不会引发异常 - 它将简单地返回Null

获取所有属性

使用XmlTextReader.MoveToAttribute (MSDN)

结合MoveToAttribute和AttributeCount属性使用:

case XmlNodeType.Element:
  Console.WriteLine(textReader.Name);
  Console.WriteLine(textReader.Value);
  for (int attInd = 0; attInd < textReader.AttributeCount; attInd++){
      textReader.MoveToAttribute( attInd );
      Console.WriteLine(textReader.Name);
      Console.WriteLine(textReader.Value);
  }
  textReader.MoveToElement(); 

1
谢谢,这正是我要找的。只有一个快速的跟进问题 - 你知道是否有一个函数可以获取节点中的每个属性,还是我必须手动完成? - weskpga
我认为ghord的答案可能会更高效,因为在读取属性后,您不必倒回文本阅读器。但是我没有测试过,所以我不知道它会有多大的差异(可能不大)。我建议您选择使代码易于阅读的选项,然后在测试显示出显著性能瓶颈时进行重构。 - JDB

22

您可以稍微更改循环条件,使其也遍历属性:

while (textReader.MoveToNextAttribute() || textReader.Read())
{ 
     switch (textReader.NodeType)
     {
         case XmlNodeType.Element:
             Console.WriteLine(textReader.Name);
             Console.WriteLine(textReader.Value);
             break;
         //...
         case XmlNodeType.Attribute:
             //use textReader.Name and textReader.Value here for attribute name and value
             break;
    }
}

MoveToNextAttribute 方法将读取器推进到当前元素中的下一个属性,如果无法这样做,则返回 false。


1
这是一个不错的想法,我一直在尝试测试但没有结果,但没有注意到while语句中至关重要的添加textReader.MoveToNextAttribute()! - wired00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接