【问题标题】:using XmlReader to get child nodes without knowing their names(in .net)使用 XmlReader 在不知道其名称的情况下获取子节点(在 .net 中)
【发布时间】:2015-10-17 04:26:55
【问题描述】:

如何在.net 中使用XmlReader 获取根节点的顶级子节点(unknownA)?因为他们的名字未知ReadToDescendant(string)ReadToNextSibling(string) 将不起作用。

<root>
    <unknownA/>
    <unknownA/>
    <unknownA>
        <unknownB/>
        <unknownB/>
    </unknownA>
    <unknownA/>
    <unknownA>
        <unknownB/>
        <unknownB>
            <unknownC/>
            <unknownC/>
        </unknownB>
    </unknownA>
    <unknownA/>
</root>

【问题讨论】:

  • 当您说“获取节点”时,您是什么意思?您只是想获取元素名称,还是每个节点的所有内容或什么?另外,您是否考虑过使用 XElement 之类的东西,而不是直接使用 XmlReader?它更容易使用。
  • @BrianRogers 我正在进行嵌套反序列化。是的,我考虑过XmlDocument。但是XmlReader 效率更高吧?
  • 您在寻找XmlReader.Skip()吗?
  • 取决于——你的 XML 有多大?如果它很小,那就无所谓了。如果它很大,您仍然可以将XElement 与 XmlReader 结合使用,以非常小的内存占用通过 XML 流式传输。参见XNode.ReadFrom方法的备注和示例代码。
  • @dbc 谢谢!我终于用Skip()了。

标签: c# .net xml xmlreader


【解决方案1】:

您可以使用XmlReader.Read() 遍历文件,检查当前Depth 与初始深度,直到到达初始深度处的元素末端,使用以下扩展方法:

public static class XmlReaderExtensions
{
    public static IEnumerable<string> ReadChildElementNames(this XmlReader xmlReader)
    {
        if (xmlReader == null)
            throw new ArgumentNullException();
        if (xmlReader.NodeType == XmlNodeType.Element && !xmlReader.IsEmptyElement)
        {
            var depth = xmlReader.Depth;
            while (xmlReader.Read())
            {
                if (xmlReader.Depth == depth + 1 && xmlReader.NodeType == XmlNodeType.Element)
                    yield return xmlReader.Name;
                else if (xmlReader.Depth == depth && xmlReader.NodeType == XmlNodeType.EndElement)
                    break;
            }
        }
    }

    public static bool ReadToFirstElement(this XmlReader xmlReader)
    {
        if (xmlReader == null)
            throw new ArgumentNullException();
        while (xmlReader.NodeType != XmlNodeType.Element)
            if (!xmlReader.Read())
                return false;
        return true;
    }
}

那么可以这样使用:

        var xml = GetXml(); // Your XML string

        using (var textReader = new StringReader(xml))
        using (var xmlReader = XmlReader.Create(textReader))
        {
            xmlReader.ReadToFirstElement();
            var names = xmlReader.ReadChildElementNames().ToArray();
            Console.WriteLine(string.Join("\n", names));
        }

【讨论】:

    猜你喜欢
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多