使用 XmlReader 读取属性值

Posted

技术标签:

【中文标题】使用 XmlReader 读取属性值【英文标题】:Reading attribute values with 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”,依此类推。

【问题讨论】:

【参考方案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() 中的关键添加!

以上是关于使用 XmlReader 读取属性值的主要内容,如果未能解决你的问题,请参考以下文章

XmlReader:无法解析不带引号的属性

PHP XMLReader 读取、编辑节点、编写 XMLWriter

是否可以使用 xmlreader 更改节点值?

C# 使用 XmlReader 但不使用 XmlDocument 获取额外的空白值

java如何读取xml节点元素值?

xml 文档异常中禁止的 DTD