C# 如何获得具有相同名称的所有XML节点,而不知道它们的级别?

C# 如何获得具有相同名称的所有XML节点,而不知道它们的级别?,c#,xml,.net-3.0,C#,Xml,.net 3.0,我有一个XML示例: <Fruits> <Red_fruits> <Red_fruits></Red_fruits> </Red_fruits> <Yellow_fruits> <banana></banana> </Yellow_fruits> <Red_fruits> <Red_f

我有一个XML示例:

<Fruits>
    <Red_fruits>
        <Red_fruits></Red_fruits>
    </Red_fruits>
    <Yellow_fruits>
        <banana></banana>
    </Yellow_fruits>
    <Red_fruits>
        <Red_fruits></Red_fruits>
    </Red_fruits>
</Fruits>
这是归还我所有的红色水果,而不仅仅是那些属于水果的

我不能使XmlNodeList=doc.SelectNodes(“/Fruits/Red#u Fruits”),因为我想用这段代码读取随机XML文件,所以我不知道特定节点的确切名称,我只需要使用C语言将具有相同名称和级别的所有节点放入XmlNodeList


有没有一种不用LINQ就可以实现的方法?如何做到这一点?

如果您只是试图找到单个节点的“下一个”或“上一个”迭代,您可以执行以下操作,然后将其与名称进行比较

XmlNode current = doc.SelectSingleNode("Fruits").SelectSingleNode("Red_fruits");

XmlNode previous = current.NextSibling;
XmlNode next = current.NextSibling;
你可以迭代直到找到合适的兄弟姐妹

while(next.Name != current.Name)
{
    next = next.NextSibling;
}
或者,您甚至可以通过调用“Parent”属性来获取列表

XmlNodeList list = current.ParentNode.SelectNodes(current.Name);

在最坏的情况下,您可以循环浏览selectedNodeList中的XMLNode项并检查ParentNode属性。如有必要,您可以对ParentNode进行递归检查,并计算到达根节点所需的次数。这将为您提供节点的深度。或者,您可以在每个级别比较ParentNode,看看它是否是您感兴趣的父节点,如果该父节点不是根节点

    public void Test(){


        XmlDocument doc = new XmlDocument();
        string selectedTag = cmbX.text;

        if (File.Exists(txtFile.text))
        {
            try
            {
                //Load
                doc.Load(cmbFile.text);

                //Select Nodes
                XmlNodeList selectedNodeList = doc.SelectNodes(".//" + selectedTag);
                List<XmlNode> result = new List<XmlNode>();
                foreach(XmlNode node in selectedNodeList){
                    if(depth(node) == 2){
                        result.Add(node);
                    }
                }
                // result now has all the selected tags of depth 2
            }
            Catch
            {
                MessageBox.show("Some error message here");
            } 
        }

    }

    private int depth(XmlNode node) {
        int depth = 0;
        XmlNode parent = node.ParentNode;
        while(parent != null){
            parent = node.ParentNode;
            depth++;
        }
        return depth;
    }
公共无效测试(){
XmlDocument doc=新的XmlDocument();
字符串selectedTag=cmbX.text;
if(File.Exists(txtFile.text))
{
尝试
{
//装载
单据加载(cmbFile.text);
//选择节点
XmlNodeList selectedNodeList=doc.SelectNodes(“./”+selectedTag);
列表结果=新列表();
foreach(selectedNodeList中的XmlNode节点){
if(深度(节点)==2){
结果.添加(节点);
}
}
//结果现在具有深度2的所有选定标记
}
抓住
{
show(“此处有一些错误消息”);
} 
}
}
私有整数深度(XmlNode){
int深度=0;
XmlNode parent=node.ParentNode;
while(父级!=null){
parent=node.ParentNode;
深度++;
}
返回深度;
}

了解单斜杠
/
和双斜杠
/
的用法在这里会有所帮助

让我们看看
/
/
如何与根节点相关。在路径开头使用
/
时:

/a
//a
/a/b
/a//b
它将定义节点
a
相对于根的绝对路径。因此,在本例中,它只会在XML树的根上找到
a
节点

在路径开头使用
/
时:

/a
//a
/a/b
/a//b
它将定义到XML文档中任意位置的节点
a
的路径。因此,在本例中,它将找到位于XML树中任何深度的
a
节点

这些XPath表达式也可以用在XPath值的中间来定义祖先后代关系。当在路径的中间使用<代码> /<代码>:

/a
//a
/a/b
/a//b
它将定义节点
b
的路径,该路径是节点
a
的直接后代(即子代)

>在路径的中间使用代码>//:

/a
//a
/a/b
/a//b
它将定义节点
b
的路径,该路径是节点
a
的任何后代

回到你的问题:

//使用return返回所有名为Red_的元素

XmlDocument doc = new XmlDocument();
XmlNodeList nodes= doc.GetElementsByTagName("Red_Fruits"); 
//使用方法

//这将选择
元素的所有子元素


如果
是根元素,请使用Xpath:
/Fruits/Red\u Fruits
。[一个斜杠
/
]

你真的尝试了吗?我不认为为什么限制“不使用LINQ”?我要做的是按深度将你得到的结果分组,然后选择你想要的组。基本上,我不认为你可以实现“所有标签在同一深度”,而不回答“与什么深度相同”的问题?我无法使用LINQ,因为我的vs版本是2005:/@IAbstract旧vs版本不支持新版本中的语言功能。与LINQ的扩展方法类似。这正是我所需要的,简单的一行:XmlNodeList=current.ParentNode.SelectNodes(current.Name);工作很好。我将测试你和其他人给出的其他解决方案,但提前非常感谢。