Reading Xml with XmlReader in C#

后端 未结 7 2066
南旧
南旧 2020-11-22 09:02

I\'m trying to read the following Xml document as fast as I can and let additional classes manage the reading of each sub block.


             


        
7条回答
  •  有刺的猬
    2020-11-22 10:01

    We do this kind of XML parsing all the time. The key is defining where the parsing method will leave the reader on exit. If you always leave the reader on the next element following the element that was first read then you can safely and predictably read in the XML stream. So if the reader is currently indexing the element, after parsing the reader will index the closing tag.

    The parsing code looks something like this:

    public class Account
    {
        string _accountId;
        string _nameOfKin;
        Statements _statmentsAvailable;
    
        public void ReadFromXml( XmlReader reader )
        {
            reader.MoveToContent();
    
            // Read node attributes
            _accountId = reader.GetAttribute( "accountId" );
            ...
    
            if( reader.IsEmptyElement ) { reader.Read(); return; }
    
            reader.Read();
            while( ! reader.EOF )
            {
                if( reader.IsStartElement() )
                {
                    switch( reader.Name )
                    {
                        // Read element for a property of this class
                        case "NameOfKin":
                            _nameOfKin = reader.ReadElementContentAsString();
                            break;
    
                        // Starting sub-list
                    case "StatementsAvailable":
                        _statementsAvailable = new Statements();
                        _statementsAvailable.Read( reader );
                        break;
    
                        default:
                            reader.Skip();
                    }
                }
                else
                {
                    reader.Read();
                    break;
                }
            }       
        }
    }
    

    The Statements class just reads in the node

    public class Statements
    {
        List _statements = new List();
    
        public void ReadFromXml( XmlReader reader )
        {
            reader.MoveToContent();
            if( reader.IsEmptyElement ) { reader.Read(); return; }
    
            reader.Read();
            while( ! reader.EOF )
            {
                if( reader.IsStartElement() )
                {
                    if( reader.Name == "Statement" )
                    {
                        var statement = new Statement();
                        statement.ReadFromXml( reader );
                        _statements.Add( statement );               
                    }
                    else
                    {
                        reader.Skip();
                    }
                }
                else
                {
                    reader.Read();
                    break;
                }
            }
        }
    }
    

    The Statement class would look very much the same

    public class Statement
    {
        string _satementId;
    
        public void ReadFromXml( XmlReader reader )
        {
            reader.MoveToContent();
    
            // Read noe attributes
            _statementId = reader.GetAttribute( "statementId" );
            ...
    
            if( reader.IsEmptyElement ) { reader.Read(); return; }
    
            reader.Read();
            while( ! reader.EOF )
            {           
                ....same basic loop
            }       
        }
    }
    

提交回复
热议问题