Мне нужно получить идентификатор идентификатора пользователя, соответствующий идентификатору терминала. любая помощь. Но это дает ошибку:
Метод 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>
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
.
using (XmlReader reader
)XmlReader
очень неэффективен. вы рассматриваете возможность использованияXDocument
илиXPath
? всего несколько строк кода; или вам нужно придерживатьсяXmlReader
?