C#中 xml文件遍历?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中 xml文件遍历?相关的知识,希望对你有一定的参考价值。

给定以下XML文件,完成代码。
<FileSystem>
<DriverC>
<Dir DirName=”dir1”>
<File FileName =”file11.txt” ></File>
<File FileName =”file12.txt” ></File>
<File FileName =”file13.txt” ></File>
<Dir DirName=”dir12”>
<File FileName =”file121.txt” ></File>
<File FileName =”file122.txt” ></File>
<File FileName =”file123.txt” ></File>
</Dir>
</Dir>
<Dir DirName=”dir2”>
<File FileName =”file21.txt” ></File>
<File FileName =”file22.txt” ></File>
<File FileName =”file23.txt” ></File>
</Dir>
</DriverC>
</FileSystem>
请使用递归算法遍历所有文件名(FileName)。

参考技术A 你不就是想要包含所有文件名的集合吗?
在C#中这个很方便啊,利用linq和xdocument,xelement几句就可以完成啊;
1.用XDocument doc=XDocument.Load(你的xml文件及路径);
2.XElement root=doc.element("FileSystem")
3.IEnumerable<XElement> files=from filename in root..Descendants() where filename.Attribute("FileName")!=null select filename;
4.开始遍历files集合
foreach (XElement xel in files)

Console.Write(xle.Attribute("FileName").Value.toString());

很肯定,经过这几个步骤肯定能够完成你的目标,
不明白继续和我交流
参考技术B DataSet mycar = new DataSet();
mycar.ReadXml(MapPath("FileName.xml"));

自己遍历去吧dataset 都不会的话别当程序员了本回答被提问者采纳

递归,将带有属性的xml文件解析为treeview c#

【中文标题】递归,将带有属性的xml文件解析为treeview c#【英文标题】:Recursion, parsing xml file with attributes into treeview c# 【发布时间】:2015-05-12 15:37:53 【问题描述】:

我目前正在处理一个项目,其中应用程序将接收 XML 文件并将其显示到 C# 中的树视图中。我正在使用 Visual Studio 10 编写此代码。

我无法限制属性显示的次数。我使用 foreach 循环遍历它拥有的每个属性并显示它,但它为节点下的每个子节点显示一次属性。如何修改此代码以仅显示一次属性?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace xmlToTreeview

    public partial class Form1 : Form
    
        string samplePath = Application.StartupPath + @"\\sample.xml";
        public Form1()
        
            InitializeComponent();
            DisplayTreeView(samplePath);
        

        private void DisplayTreeView(string pathname)
        
            try
            
                // SECTION 1. Create a DOM Document and load the XML data into it.
                XmlDocument dom = new XmlDocument();
                dom.Load(pathname);


                // SECTION 2. Initialize the TreeView control.
                treeView1.Nodes.Clear();
                treeView1.Nodes.Add(new TreeNode(dom.DocumentElement.Name));
                TreeNode tNode = new TreeNode();
                tNode = treeView1.Nodes[0];

                // SECTION 3. Populate the TreeView with the DOM nodes.
                AddNode(dom.DocumentElement, tNode);

            
            catch (XmlException xmlEx)
            
                MessageBox.Show(xmlEx.Message);
            
            catch (Exception ex)
            
                MessageBox.Show(ex.Message);
            
        
        private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
        
            XmlNode xNode;
            TreeNode tNode;
            XmlNodeList nodeList;
            int i;

            // Loop through the XML nodes until the leaf is reached.
            // Add the nodes to the TreeView during the looping process.

            if (inXmlNode.HasChildNodes)
            
                nodeList = inXmlNode.ChildNodes;

                for (i = 0; i <= nodeList.Count - 1; i++)
                
                    xNode = inXmlNode.ChildNodes[i];
                    inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
                    tNode = inTreeNode.Nodes[i];

                    //Check if the XmlNode has attributes
                    if (inXmlNode.Attributes.Count != 0)
                    
                        foreach (XmlAttribute att in inXmlNode.Attributes)
                        
                            inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value;
                        
                    
                    AddNode(xNode, tNode);
                
            
            else
            
                // Here you need to pull the data from the XmlNode based on the
                // type of node, whether attribute values are required, and so forth.
                inTreeNode.Text = (inXmlNode.OuterXml).Trim();
            
            treeView1.ExpandAll();
        
    

这是我的xml的一个例子

<?xml version="1.0" encoding="utf-8"?>
<DataConfiguration xmln="abcefg12345" xmlns:xsi="12345abcefg" xsi:schemaLocation="12345abcefg12345abcefg">
  <Hosts>
    <Sites>
        <Site Name="ss">
            <Host Id="aa">
                <Address Host="www.www.com"> </Address>
            </Host>
            <Host Id="ee">
                <Address Host="www.www.com"> </Address>
            </Host>
            <Host Id="dd">
                <Address Host="www.www.com"> </Address>
            </Host> 
            <Host Id="pp">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com/"/>
            </Host>
            <Host Id="ss">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
            </Host> 
            <Host Id="561">
                <Address Host="www.www.com"> </Address>
            </Host> 
        </Site>
        <Site Name="hihi">
            <Host Id="cc">
                <Address Host="www.www.com"> </Address>
            </Host>
            <Host Id="sdD">
                <Address Host="www.www.com"> </Address>
            </Host>
            <Host Id="8uj">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>

            </Host>
            <Host Id="222">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>               
            </Host>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
            </Host>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
            </Host>             
        </Site>     
    </Sites>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
            </Host>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
            </Host>
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
            </Host>         
            <Host Id="hhh">
                <Address Scheme="ppp" Host="www.www.com" Path="www.www.com"/>
            </Host>

</Hosts>
<DataPools>
    <DataPool Id="sss" default="sure">
        <DataGroup Id="sss" Parent="aaa" UserCanSelectHost="sure" >
            <HostId Parent="hhhh">I'm breaking here</HostId>
            <DataSources>
                <empty/>
            </DataSources>
        </DataGroup>
        <DataGroup Id="ccc" UserCanSelectHost="whynot" >
            <HostId>God I'm breaking here again, i hope you can fix me</HostId>
            <DataSources>
                <empty/>
            </DataSources>
        </DataGroup>
        <DataGroup Id="sss" UserCanSelectHost="yessure" >
            <HostId>cry face</HostId>
                <webfg displaygroup="sss" provider="sss" id="ccc" principal="ccc" nioarc="ccc" nap="ccc" group="ccc">
                </webfg>

                <nhood port="1234"/>
            <ServerNames>
              <!-- insert comment -->
              <!-- insert comment -->
              <!-- insert comment -->
              <ServerName>myname</ServerName>
              <ServerName>yourname</ServerName>
            </ServerNames>
            <!-- insert comment -->
            <Implementations>
              <Implementation>
                <Name>yourname</Name>
                <Type>typeme</Type>
                <Assembly>visionme</Assembly>
                <Path>ohno</Path>
              </Implementation>
            </Implementations>-->
                <cfgman port="ccc" />               
                <webservice provider="ccc"  />
                <webservice provider="ccc"  />
                <webservice provider="ccc"  />
                    <parameters>
                        <useeventpush value="ccc"/>
                    </parameters>
                <webservice provider="ccc"  />
                        <pollingFrequency value="1000"/>
        </DataGroup>
    </DataPool>
    <DataGroup Id="ccc " UserCanSelectHost="ccc" >
        <DataGroup Id="ccc " UserCanSelectHost="ccc" >
            <HostId>idk</HostId>
            <DataSources>
                <empty/>
            </DataSources>
        </DataGroup>
        <DataGroup Id="ccc " UserCanSelectHost="ccc" >
            <HostId>idk</HostId>
            <DataSources>
                <empty/>
            </DataSources>
        </DataGroup>
        <DataGroup Id="default" UserCanSelectHost="true" >
            <HostId>idk</HostId>
        </DataGroup>
    </DataGroup>    
</DataPools>    
</DataConfiguration>

【问题讨论】:

【参考方案1】:

您需要通过子节点将循环通过属性移出循环:

    private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
    
        // Loop through the XML nodes until the leaf is reached.
        // Add the nodes to the TreeView during the looping process.

        if (inXmlNode.HasChildNodes)
        
            //Check if the XmlNode has attributes
            foreach (XmlAttribute att in inXmlNode.Attributes)
            
                inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value;
            

            var nodeList = inXmlNode.ChildNodes;
            for (int i = 0; i < nodeList.Count; i++)
            
                var xNode = inXmlNode.ChildNodes[i];
                var tNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(xNode.Name))];
                AddNode(xNode, tNode);
            
        
        else
        
            // Here you need to pull the data from the XmlNode based on the
            // type of node, whether attribute values are required, and so forth.
            inTreeNode.Text = (inXmlNode.OuterXml).Trim();
        
        treeView1.ExpandAll();
    

更新

如果要过滤掉命名空间属性,可以加extension methods:

public static class XmlNodeExtensions

    public static bool IsDefaultNamespaceDeclaration(this XmlAttribute attr)
    
        if (attr == null)
            return false;
        if (attr.NamespaceURI != "http://www.w3.org/2000/xmlns/")
            return false;
        return attr.Name == "xmlns";
    

    public static bool IsNamespaceDeclaration(this XmlAttribute attr)
    
        if (attr == null)
            return false;
        if (attr.NamespaceURI != "http://www.w3.org/2000/xmlns/")
            return false;
        return attr.Name == "xmlns" || attr.Name.StartsWith("xmlns:");
    

然后用它来跳过不需要的XmlAttribute 实例。您还可以将XmlElement类型的所有节点的文本显式设置为名称+属性数据,而不仅仅是那些具有子元素的元素,仅将OuterXml用于文本节点:

    private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
    
        if (inXmlNode is XmlElement)
        
            // An element.  Display element name + attribute names & values.
            foreach (var att in inXmlNode.Attributes.Cast<XmlAttribute>().Where(a => !a.IsNamespaceDeclaration()))
            
                inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value;
            
            // Add children
            foreach (XmlNode xNode in inXmlNode.ChildNodes)
            
                var tNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(xNode.Name))];
                AddNode(xNode, tNode);
            
        
        else
        
            // Not an element.  Character data, comment, etc.  Display all text.
            inTreeNode.Text = (inXmlNode.OuterXml).Trim();
        
        treeView1.ExpandAll();
    

如果你真的想只过滤掉默认命名空间定义而留下其他的,你可以这样做:

            // An element.  Display element name + attribute names & values.
            foreach (var att in inXmlNode.Attributes.Cast<XmlAttribute>().Where(a => !a.IsDefaultNamespaceDeclaration()))
            
                inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value;
            

顺便说一句,我不建议这样做,因为以下实际上意味着同一件事,即命名空间 http://somenamespace 中具有本地名称 DataConfiguration 的元素:

<ss:DataConfiguration xmlns:ss="http://somenamespace"/>
<DataConfiguration xmlns="http://somenamespace"/>

您的树将显示第一个元素的命名空间,但不显示第二个元素。

更新 2

要将XmlDeclaration 包含在树中,请将顶层循环更改为:

        treeView1.Nodes.Clear();
        foreach (XmlNode xNode in dom.ChildNodes)
        
            var tNode = treeView1.Nodes[treeView1.Nodes.Add(new TreeNode(xNode.Name))];
            AddNode(xNode, tNode);
        

更新 3

将循环放入DisplayTreeView 中以包含XmlDeclaration 循环:

    private void DisplayTreeView(string pathname)
    
        try
        
            // SECTION 1. Create a DOM Document and load the XML data into it.
            XmlDocument dom = new XmlDocument();
            dom.Load(pathname);

            // SECTION 2. Initialize the TreeView control.
            treeView1.Nodes.Clear();

            // SECTION 3. Populate the TreeView with the XML nodes.
            foreach (XmlNode xNode in dom.ChildNodes)
            
                var tNode = treeView1.Nodes[treeView1.Nodes.Add(new TreeNode(xNode.Name))];
                AddNode(xNode, tNode);
            
        
        catch (XmlException xmlEx)
        
            MessageBox.Show(xmlEx.Message);
        
        catch (Exception ex)
        
            MessageBox.Show(ex.Message);
        
    

【讨论】:

我明白了,现在可以解决问题了,谢谢!此外,我在所有子节点后面都获得了 xmlns= 命名空间,我应该如何解决这个问题?看起来它们只在我使用 OutXml 显示剩余信息时出现。还有一个问题,节点有长度吗?因为我的评论节点在节点末尾被截断了。 @StudentPlusOne - 答案已更新。节点文本的长度没有限制。确保你的树是Scrollable 感谢您的回答,您更新的代码有效,它将删除所有包含“xmln=”的属性,但这也会从 中删除部分属性,是否有不同的方法正在做?使用扩展方法也是一件很聪明的事情,我学到了很多东西!谢谢 @StudentPlusOne - "xmln=" 是您的问题中的错字,还是您真的有一个名为 xmln 的属性?标准命名空间属性前缀是xmlns,所以我认为这是一个错误。 代码是这样的,红色表示“xmln="属性重复postimg.org/image/apmg0fpl7【参考方案2】:

尝试简单的递归算法

        static void Main(string[] args)
        
            string input =
                "<a>" +
                   "<b>" +
                      "<c>val1</c>" +
                      "<d>val2</d>" +
                   "</b>" +
                   "<e>val3</e>" +
                   "<f>val4</f>" +
               "</a>";

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(input);
            RecursiveRead(doc.DocumentElement);

        
        static string RecursiveRead(XmlNode node)
        
            List<string> children = new List<string>();
            bool done = false;

            if (node.HasChildNodes)
            
                foreach (XmlNode child in node)
                
                    children.Add(RecursiveRead(child));
                
                Console.WriteLine("table : 0; children : 1", node.Name, string.Join(",", children.ToArray()));
                //string cmd = "INSERT INTO " + second + " (" + first + ") VALUES ('" + xml.Value + "')";
                //SqlCommand command = new SqlCommand(cmd, conn);
                //command.ExecuteNonQuery();
            
            else
            
                return node.Value;
            
            return node.Name;
        

【讨论】:

以上是关于C#中 xml文件遍历?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中循环遍历 XML 的特定节点

C#不能查询XML但可以遍历节点?

c#遍历嵌套层次很多的xml

C# 遍历文件夹问题

c#怎么遍历文件夹下面的所有文件

C#遍历指定文件夹中的所有文件