Ваш элемент Reason
пропускается, потому что после того, как содержимое Code
было прочитано, средство чтения также переместилось к следующему элементу (здесь: Reason
), что заставляет последующий вызов Read
перемещаться еще на один элемент (здесь: Detail
).
Из документации ReadElementAsContentString
:
Этот метод считывает начальный тег, содержимое элемента и перемещает средство чтения за тегом конечного элемента.
Есть несколько способов решить эту проблему.
Если вы действительно хотите сохранить switch
/ case
проверка имен элементов, вы должны убедиться, что не вызываете метод Read
при вызове ReadElementContentAsString
, например:
using (XmlReader xReader = XmlReader.Create(new StringReader("<ns3:Failure xmlns:ns3=\"urn:xxxx\"><Reason>Access denied</Reason><Code>Unauthorized</Code><Detail>Invalid username/password.</Detail></ns3:Failure>")))
{
xReader.MoveToContent();
while (!xReader.EOF)
{
if (xReader.NodeType == XmlNodeType.Element)
{
switch (xReader.Name)
{
case "Code":
case "Reason":
case "Detail":
msg = msg + " " + xReader.ReadElementContentAsString();
break;
default:
xReader.Read();
break;
}
}
else
{
xReader.Read();
}
}
}
В качестве альтернативы, учитывая пример показано в вашем вопросе, вы можете просто объединить все узлы типа XmlNodeType.Text
, например:
string msg = string.Empty;
using (XmlReader xReader = XmlReader.Create(new StringReader("<ns3:Failure xmlns:ns3=\"urn:xxxx\"><Reason>Access denied</Reason><Code>Unauthorized</Code><Detail>Invalid username/password.</Detail></ns3:Failure>")))
{
while (xReader.Read())
{
if (xReader.NodeType == XmlNodeType.Text)
{
msg = msg + " " + xReader.ReadContentAsString();
}
}
}