【问题标题】:Reading attribute values with XmlReader使用 XmlReader 读取属性值
【发布时间】:2012-06-21 18:23:03
【问题描述】:

我有一个试图从here 读取的 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"/>

如何让文本阅读器读取属性值?理想的情况是打印值“货币”,然后打印其值:“F”,依此类推。

【问题讨论】:

    标签: c# xml xmlreader


    【解决方案1】:

    获取单个命名属性

    使用XmlTextReader.GetAttribute (MSDN)

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

    这个函数的一个很好的特性:如果没有定义属性,它不会导致异常 - 它只会返回Null

    获取所有属性

    使用XmlTextReader.MoveToAttribute (MSDN)

    将 AttributeCount 属性与 MoveToAttribute 结合使用:

    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(); 
    

    【讨论】:

    • 谢谢,这正是我要找的。只是一个快速的后续问题 - 你知道是否有一个函数可以获取节点中的每个属性,还是我必须手动完成?
    • 我认为ghord's answer 的性能可能会稍好一些,因为您不必在阅读属性后倒回文本阅读器。但是我还没有测试过,所以我不知道它有多大的不同(可能不多)。我建议您选择使您的代码易于阅读的选项,然后在测试显示出显着的性能瓶颈时进行重构。
    【解决方案2】:

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

    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 方法将 reader 推进到当前元素中的下一个属性,如果不能这样做,则返回 false。

    【讨论】:

    • 这是个好主意,我试图对此进行测试但没有任何结果,但没有注意到 while 语句 textReader.MoveToNextAttribute() 中的关键添加!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 2017-05-30
    • 2016-10-18
    • 2013-07-11
    • 1970-01-01
    • 2016-07-12
    相关资源
    最近更新 更多