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)。
在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=”的属性,但这也会从 "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文件遍历?的主要内容,如果未能解决你的问题,请参考以下文章