【问题标题】:How to get content of all Elements in an XML using XMLReader?如何使用 XMLReader 获取 XML 中所有元素的内容?
【发布时间】:2020-07-14 18:38:53
【问题描述】:

我正在使用 XMLReader 读取给定 XML 中的所有元素,但未检索到某些元素的内容。

一个例子:

string msg = string.Empty;
using (XmlReader xReader = XmlReader.Create(new StringReader("<ns3:Failure xmlns:ns3=\"urn:xxxx\"><Code>Unauthorized</Code><Reason>Access denied</Reason><Detail>Invalid username/password.</Detail></ns3:Failure>")))
{
    while (xReader.Read())
    {
        if (xReader.NodeType == XmlNodeType.Element)
        {
            switch (xReader.Name)
            {
                case "Code":
                    msg = msg + " " + xReader.ReadElementContentAsString();
                    break;
                case "Reason":
                    msg = msg + " " + xReader.ReadElementContentAsString();
                    break;
                case "Detail":
                    msg = msg + " " + xReader.ReadElementContentAsString();
                    break;

            }
        }
    }
}

执行上述代码后,msg 的值为“Unauthorized Invalid username/password.”
缺少&lt;Reason&gt; 的内容。
预期值应为“未经授权的访问被拒绝无效的用户名/密码。”

如何获取所有元素的内容?

【问题讨论】:

  • 你不是递归地阅读文档——你只是阅读一次。
  • @DanielA.White 是的,文档被读取一次,然后递归读取每个元素。问题是我可以获得 和 <detail> 的内容,但不能获得 <reason></reason></detail> 的内容

标签: c# .net xmlreader


【解决方案1】:

您的Reason 元素被跳过,因为在阅读了Code 的内容之后,阅读器也移动到了下一个元素(这里:Reason),这使得随后对Read 的调用移动更进一步的一个元素(这里:Detail)。

来自ReadElementAsContentString的文档:

这个方法读取开始标签,元素的内容,和 将阅读器移过结束元素标签。

解决这个问题的方法不止一种。

如果您真的想保留switch/case 检查元素名称,则必须确保在调用ReadElementContentAsString 时不调用Read 方法,例如:

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();
        }
    }     
}

【讨论】:

  • 明白。非常感谢@pfx
猜你喜欢
  • 1970-01-01
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
  • 2013-09-24
  • 2016-01-10
相关资源
最近更新 更多