I'd like to get all the element name from a xml file, for example the xml file is,
我想从xml文件中获取所有元素名,例如xml文件是,
<BookStore>
<BookStoreInfo>
<Address />
<Tel />
<Fax />
<BookStoreInfo>
<Book>
<BookName />
<ISBN />
<PublishDate />
</Book>
<Book>
....
</Book>
</BookStore>
I would like to get the element's name of "BookName". "ISBN" and "PublishDate " and only those names, not include " BookStoreInfo" and its child node's name
我希望得到元素的名称为“BookName”。“ISBN”和“PublishDate”以及只有这些名称,不包括“BookStoreInfo”及其子节点的名称
I tried several ways, but doesn't work, how can I do it?
我试了好几种方法,但都没用,我怎么做呢?
8 个解决方案
#1
29
Well, with XDocument
and LINQ-to-XML:
好的,使用XDocument和linqto - xml:
foreach(var name in doc.Root.DescendantNodes().OfType<XElement>()
.Select(x => x.Name).Distinct())
{
Console.WriteLine(name);
}
There are lots of similar routes, though.
不过也有很多类似的路线。
#2
9
Using XPath
使用XPath
XmlDocument xdoc = new XmlDocument();
xdoc.Load(something);
XmlNodeList list = xdoc.SelectNodes("//BookStore");
gives you a list with all nodes in the document named BookStore
给出一个包含名为BookStore的文档中的所有节点的列表
#3
5
I agree with Adam, the ideal condition is to have a schema that defines the content of xml document. However, sometimes this is not possible. Here is a simple method for iterating all of the nodes of an xml document and using a dictionary to store the unique local names. I like to keep track of the depth of each local name, so I use a list of int to store the depth. Note that the XmlReader is "easy on the memory" since it does not load the entire document as the XmlDocument does. In some instances it makes little difference because the size of the xml data is small. In the following example, an 18.5MB file is read with an XmlReader. Using an XmlDocument to load this data would have been less effecient than using an XmlReader to read and sample its contents.
我同意Adam的观点,理想的情况是有一个定义xml文档内容的模式。然而,有时这是不可能的。这里有一个简单的方法,用于迭代xml文档的所有节点,并使用字典存储惟一的本地名称。我喜欢跟踪每个本地名称的深度,所以我使用一个int列表来存储深度。注意,XmlReader“对内存很容易”,因为它不像XmlDocument那样加载整个文档。在某些情况下,由于xml数据的大小很小,所以没有什么区别。在下面的示例中,使用XmlReader读取一个18.5MB的文件。使用XmlDocument加载这些数据要比使用XmlReader读取和示例其内容的效率要低。
string documentPath = @"C:\Docs\cim_schema_2.18.1-Final-XMLAll\all_classes.xml";
Dictionary<string, List<int>> nodeTable = new Dictionary<string, List<int>>();
using (XmlReader reader = XmlReader.Create(documentPath))
{
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element)
{
if (!nodeTable.ContainsKey(reader.LocalName))
{
nodeTable.Add(reader.LocalName, new List<int>(new int[] { reader.Depth }));
}
else if (!nodeTable[reader.LocalName].Contains(reader.Depth))
{
nodeTable[reader.LocalName].Add(reader.Depth);
}
}
reader.Read();
}
}
Console.WriteLine("The node table has {0} items.",nodeTable.Count);
foreach (KeyValuePair<string, List<int>> kv in nodeTable)
{
Console.WriteLine("{0} [{1}]",kv.Key, kv.Value.Count);
for (int i = 0; i < kv.Value.Count; i++)
{
if (i < kv.Value.Count-1)
{
Console.Write("{0}, ", kv.Value[i]);
}
else
{
Console.WriteLine(kv.Value[i]);
}
}
}
#4
4
The purists way of doing this (and, to be fair, the right way) would be to have a schema contract definition and read it in that way. That being said, you could do something like this...
纯粹主义者这样做(而且,公平地说,正确的方式)是有一个模式契约定义并以这种方式阅读。也就是说,你可以做这样的事情……
List<string> nodeNames = new List<string>();
foreach(System.Xml.XmlNode node in doc.SelectNodes("BookStore/Book"))
{
foreach(System.Xml.XmlNode child in node.Children)
{
if(!nodeNames.Contains(child.Name)) nodeNames.Add(child.Name);
}
}
This is, admittedly, a rudimentary method for obtaining the list of distinct node names for the Book
node's children, but you didn't specify much else in the way of your environment (if you have 3.5, you could use LINQ to XML to make this a little prettier, for example), but this should get the job done regardless of your environment.
诚然,这是一个基本的方法获取不同的列表为本节点的孩子节点名称,但是你没有指定其他的环境(如果你有3.5,您可以使用LINQ to XML使这一点更漂亮,例如),但这应该完成工作不管你的环境。
#5
3
If you're using C# 3.0, you can do the following:
如果你使用c# 3.0,你可以做以下事情:
var data = XElement.Load("c:/test.xml"); // change this to reflect location of your xml file
var allElementNames =
(from e in in data.Descendants()
select e.Name).Distinct();
#6
2
You can try doing it using XPATH.
您可以尝试使用XPATH进行此操作。
XmlDocument doc = new XmlDocument();
doc.LoadXml("xml string");
XmlNodeList list = doc.SelectNodes("//BookStore/Book");
#7
2
If BookStore is ur root element then u can try following code
如果BookStore是您的根元素,那么您可以尝试执行以下代码
XmlDocument doc = new XmlDocument();
doc.Load(configPath);
XmlNodeList list = doc.DocumentElement.GetElementsByTagName("Book");
if (list.Count != 0)
{
for (int i = 0; i < list[0].ChildNodes.Count; i++)
{
XmlNode child = list[0].ChildNodes[i];
}
}
#8
0
An online tool I find here can extract those elements 's names beautifully - just uploading the XML file and they print the names as a result webpage.
我在这里找到的一个在线工具可以很好地提取这些元素的名称——只需上传XML文件,它们就会打印出这些名称作为结果页面。
http://taporware.ualberta.ca/~taporware/xmlTools/listxml.shtml
http://taporware.ualberta.ca/ taporware / xmlTools / listxml.shtml
#1
29
Well, with XDocument
and LINQ-to-XML:
好的,使用XDocument和linqto - xml:
foreach(var name in doc.Root.DescendantNodes().OfType<XElement>()
.Select(x => x.Name).Distinct())
{
Console.WriteLine(name);
}
There are lots of similar routes, though.
不过也有很多类似的路线。
#2
9
Using XPath
使用XPath
XmlDocument xdoc = new XmlDocument();
xdoc.Load(something);
XmlNodeList list = xdoc.SelectNodes("//BookStore");
gives you a list with all nodes in the document named BookStore
给出一个包含名为BookStore的文档中的所有节点的列表
#3
5
I agree with Adam, the ideal condition is to have a schema that defines the content of xml document. However, sometimes this is not possible. Here is a simple method for iterating all of the nodes of an xml document and using a dictionary to store the unique local names. I like to keep track of the depth of each local name, so I use a list of int to store the depth. Note that the XmlReader is "easy on the memory" since it does not load the entire document as the XmlDocument does. In some instances it makes little difference because the size of the xml data is small. In the following example, an 18.5MB file is read with an XmlReader. Using an XmlDocument to load this data would have been less effecient than using an XmlReader to read and sample its contents.
我同意Adam的观点,理想的情况是有一个定义xml文档内容的模式。然而,有时这是不可能的。这里有一个简单的方法,用于迭代xml文档的所有节点,并使用字典存储惟一的本地名称。我喜欢跟踪每个本地名称的深度,所以我使用一个int列表来存储深度。注意,XmlReader“对内存很容易”,因为它不像XmlDocument那样加载整个文档。在某些情况下,由于xml数据的大小很小,所以没有什么区别。在下面的示例中,使用XmlReader读取一个18.5MB的文件。使用XmlDocument加载这些数据要比使用XmlReader读取和示例其内容的效率要低。
string documentPath = @"C:\Docs\cim_schema_2.18.1-Final-XMLAll\all_classes.xml";
Dictionary<string, List<int>> nodeTable = new Dictionary<string, List<int>>();
using (XmlReader reader = XmlReader.Create(documentPath))
{
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element)
{
if (!nodeTable.ContainsKey(reader.LocalName))
{
nodeTable.Add(reader.LocalName, new List<int>(new int[] { reader.Depth }));
}
else if (!nodeTable[reader.LocalName].Contains(reader.Depth))
{
nodeTable[reader.LocalName].Add(reader.Depth);
}
}
reader.Read();
}
}
Console.WriteLine("The node table has {0} items.",nodeTable.Count);
foreach (KeyValuePair<string, List<int>> kv in nodeTable)
{
Console.WriteLine("{0} [{1}]",kv.Key, kv.Value.Count);
for (int i = 0; i < kv.Value.Count; i++)
{
if (i < kv.Value.Count-1)
{
Console.Write("{0}, ", kv.Value[i]);
}
else
{
Console.WriteLine(kv.Value[i]);
}
}
}
#4
4
The purists way of doing this (and, to be fair, the right way) would be to have a schema contract definition and read it in that way. That being said, you could do something like this...
纯粹主义者这样做(而且,公平地说,正确的方式)是有一个模式契约定义并以这种方式阅读。也就是说,你可以做这样的事情……
List<string> nodeNames = new List<string>();
foreach(System.Xml.XmlNode node in doc.SelectNodes("BookStore/Book"))
{
foreach(System.Xml.XmlNode child in node.Children)
{
if(!nodeNames.Contains(child.Name)) nodeNames.Add(child.Name);
}
}
This is, admittedly, a rudimentary method for obtaining the list of distinct node names for the Book
node's children, but you didn't specify much else in the way of your environment (if you have 3.5, you could use LINQ to XML to make this a little prettier, for example), but this should get the job done regardless of your environment.
诚然,这是一个基本的方法获取不同的列表为本节点的孩子节点名称,但是你没有指定其他的环境(如果你有3.5,您可以使用LINQ to XML使这一点更漂亮,例如),但这应该完成工作不管你的环境。
#5
3
If you're using C# 3.0, you can do the following:
如果你使用c# 3.0,你可以做以下事情:
var data = XElement.Load("c:/test.xml"); // change this to reflect location of your xml file
var allElementNames =
(from e in in data.Descendants()
select e.Name).Distinct();
#6
2
You can try doing it using XPATH.
您可以尝试使用XPATH进行此操作。
XmlDocument doc = new XmlDocument();
doc.LoadXml("xml string");
XmlNodeList list = doc.SelectNodes("//BookStore/Book");
#7
2
If BookStore is ur root element then u can try following code
如果BookStore是您的根元素,那么您可以尝试执行以下代码
XmlDocument doc = new XmlDocument();
doc.Load(configPath);
XmlNodeList list = doc.DocumentElement.GetElementsByTagName("Book");
if (list.Count != 0)
{
for (int i = 0; i < list[0].ChildNodes.Count; i++)
{
XmlNode child = list[0].ChildNodes[i];
}
}
#8
0
An online tool I find here can extract those elements 's names beautifully - just uploading the XML file and they print the names as a result webpage.
我在这里找到的一个在线工具可以很好地提取这些元素的名称——只需上传XML文件,它们就会打印出这些名称作为结果页面。
http://taporware.ualberta.ca/~taporware/xmlTools/listxml.shtml
http://taporware.ualberta.ca/ taporware / xmlTools / listxml.shtml