чтение xml с использованием xml parser

1

Мне нужно получить идентификатор идентификатора пользователя, соответствующий идентификатору терминала. любая помощь. Но это дает ошибку:

Метод ReadElementContentAsString не поддерживается для типа узла None. Строка 1, позиция 668.

 string strTerminalId = "E";
 XmlDocument xdoc = new XmlDocument();
 xdoc.LoadXml(STRING); //
 string strxml = xdoc.OuterXml;
 string strUserName = "";
 bool Flag = false;

 using (XmlReader reader = XmlReader.Create(new StringReader(strxml)))
 {
     while (reader.Read())
     {
         if (reader.IsStartElement())
         {
             switch (reader.Name)
             {
                 case "Row":
                     reader.Read();
                     if (Flag == false)
                     {
                         reader.ReadToFollowing("TERM-ID");
                         reader.Read();
                         string strTERMID = reader.ReadElementContentAsString().ToString();
                          if (strTERMID == strTerminalId)
                                {
                                    while (reader.ReadToFollowing("NA") && (Flag == false))
                                    {
                                        reader.Read();
                                        string strUser = reader.ReadContentAsString();
                                        if (strUser == "NA")
                                        {
                                            reader.ReadToFollowing("c:value");
                                            reader.Read();
                                            strUserName = reader.ReadContentAsString();
                                            Flag = true;
                                        }
                                    }
                                }
                            }
                            break;
                    }
                }
            }

Содержимое документа XML

<GetReferenceTableResponse xmlns='http://tempuri.org/'>
    <GetReferenceTableResult> 
        <Table Name='C' ID='46899' xmlns=''>   
            <Columns>
            <Col ID='7442' Name='TD' Datatype='T' Length='8' AttributeDescription='Terminal ID' IsKey='Y'/>
            <Col ID='7443' Name='D' Datatype='T' Length='50' AttributeDescription='Description' IsKey=' '/>
            <Col ID='7444' Name='U' Datatype='T' Length='8' AttributeDescription='USER-ID' IsKey='' />
            </Columns> 
            <Rows>
                <Row RowsetID=\"1\">
                    <TERM-ID ID='279598'>A</TERM-ID>
                    <DESC-TXT ID='279622'>ASC</DESC-TXT>  
                    <USER-ID ID='279646'>A</USER-ID>
                </Row>
            </Rows> 
        </Table> 
    </GetReferenceTableResult>
</GetReferenceTableResponse>
  • 0
    в чем ошибка? отредактируйте свой вопрос, предоставив больше деталей, и лучше предоставьте весь код внутри оператора using (XmlReader reader )
  • 1
    Разбор XML-документа с использованием XmlReader очень неэффективен. вы рассматриваете возможность использования XDocument или XPath ? всего несколько строк кода; или вам нужно придерживаться XmlReader ?
Показать ещё 3 комментария
Теги:
xmlreader

1 ответ

1
Лучший ответ

ReadToFollowing переходит к ближайшему элементу с заданным именем, и следующий Read будет проходить внутри этого элемента - прямо к тексту. Поэтому в обоих случаях вам понадобится ReadContentAsString.

В вашем случае это будет работать:

using (XmlReader reader = XmlReader.Create(new StringReader(strxml)))
{
    while (reader.Read())
    {
        if (reader.IsStartElement())
        {
            switch (reader.Name)
            {
                case "Row":                     
                    if (!Flag)
                    {
                        reader.ReadToFollowing("TERM-ID");
                        reader.Read();
                        string strTERMID = reader.ReadContentAsString();                         
                        if (strTERMID == strTerminalId && reader.ReadToNextSibling("USER-ID"))
                        {
                            reader.Read();
                            strUserName = reader.ReadContentAsString();
                            Flag = true;
                        }
                    }
                    break;
            }
        }
    }
}

Я удалил первый Read сразу после case "Row": - в противном случае вы пропустили бы правильный элемент и также удалили ReadToFollowing("USER-ID") из цикла while - это просто, чтобы войти в элемент только один раз.

Но, как сказал @kennyzx, гораздо проще разбирать xml с помощью XDoccument.

UPDATE Я не уверен в вашей схеме, но если возможно, что элемент Row не имеет идентификатор пользователя, то с помощью ReadToFollowing можно перейти к следующему доступному элементу "User-ID", даже если он не находится в тот же элемент "Row". Поэтому во втором случае лучше использовать ReadToNextSibling.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню