考虑以下需要解析的XML内容。
<root>
<item>
<itemId>001</itemId>
<itemName>test 1</itemName>
<description/>
</item>
</root>
我需要解析每个标签并将其存储到表中,如下所示:
TAG_NAME TAG_VALUE IsContainer
------------ -------------- -----------
root null true
item null true
itemId 001 false
itemName test 1 false
description null false
/item null true
/root null true
现在,为了完成这个任务,我使用
XmlReader
,因为它允许我们解析每一个节点。我的做法如下:
我创建了以下类来包含每个标签的数据。
public class XmlTag
{
public string XML_TAG { get; set; }
public string XML_VALUE { get; set; }
public bool IsContainer { get; set; }
}
我正在尝试获取标签列表(包括闭合标签),如下所示:
private static List<XmlTag> ParseXml(string path)
{
var tags = new List<XmlTag>();
using (var reader = XmlReader.Create(path))
{
while (reader.Read())
{
var tag = new XmlTag();
bool shouldAdd = false;
switch (reader.NodeType)
{
case XmlNodeType.Element:
shouldAdd = true;
tag.XML_TAG = reader.Name;
//How do I get the VALUE of current reader?
//How do I determine if the current node contains children nodes to set IsContainer property of XmlTag object?
break;
case XmlNodeType.EndElement:
shouldAdd = true;
tag.XML_TAG = string.Format("/{0}", reader.Name);
tag.XML_VALUE = null;
//How do I determine if the current closing node belongs to a node which had children.. like ROOT or ITEM in above example?
break;
}
if(shouldAdd)
tags.Add(tag);
}
}
return tags;
}
但我在确定以下内容方面遇到了困难:
- 如何确定当前的
ELEMENT
是否包含子 XML 节点?以设置IsContainer
属性。 - 如果当前节点是
XmlNodeType.Element
类型,如何获取其值。
编辑:
我尝试使用 LINQ to XML,如下所示:
var xdoc = XDocument.Load(@"SampleItem.xml");
var tags = (from t in xdoc.Descendants()
select new XmlTag
{
XML_TAG = t.Name.ToString(),
ML_VALUE = t.HasElements ? null : t.Value,
IsContainer = t.HasElements
}).ToList();
这个方法可以给我XML标记和它们的值,但是它并不能给我包含闭合标记在内的所有标记。这就是为什么我决定尝试使用XmlReader
。但如果我在LINQ to XML示例中漏掉了什么,请纠正我。
XmlReader
吗?除非您担心将大文件加载到内存中,否则使用LINQ to XML(甚至只是XmlDocument)会使生活更加简单。 - Jon Skeet