C# 操作xml文件

Basic operaiton on xml file in C#

Background of XML

XML document can be divied into three kinds of schema, DTD, XDR and XSD.

Open xml file in synchronous way

XmlDocument xml = new XmlDocument();
xml.Load(file);
The XmlDocument class does not implement IDisposable, so there is no way to force it to release it's resources at will. If you really need to immediately free the memory used by XmlDocument, the only way to do that would be to do the following:
nodes = null;
xml = null;
GC.Collect();
GC.WaitForPendingFinalizers();
If omiting the last line, the garbage collection still not work immediately.
XmlDocument always loads the entire document into memory at once. If you simply want to iterate through the nodes in the document as a stream, only loading a bit at a time, that is what the XmlReader class is for. However, you lose a lot of functionality that way. There is no way to select nodes via XPath, for instance, as you where doing in your example.
Open xml file in asynchronous way
The XmlReader class is an abstract base class that provides non-cached, forward-only, read-only access to XML data.
When reading a large text node, XmlReader may only cache a partial text value and return the text node, so retrieving Value may be blocked by an IO operation. Use the GetValueAsync method to get the text value in asynchronous mode. You may also use ReadValueChunkAsync to read a large text block chunk-by-chunk.
Comparison of XmlReader and XmlDocument
XmlReader usage
XmlReader class Represents a reader that provides fast, noncached, forward-only access to XML data. But the defect is single way, never fallback, only read.
Define a XmlReaderSetting to restrict or improve the performance of underly reader stream in XmlReader instance. For example:
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
settings.IgnoreProcessingInstructions = true;
settings.IgnoreWhitespace = true;
settings.CheckCharacters = false;
settings.CloseInput = true;
XmlReader xml = XmlReader.Create(file, settings);
Using XmlReadr is simalar to manipulate input stream, invoking member function Read to move to next node. The NoteType property of XmlReader represents the exact type of current line. For example, if current line is <…>, that the node type is Element.  So it needs custume parsing accroding to different note type.
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
settings.IgnoreProcessingInstructions = true;
settings.IgnoreWhitespace = true;
settings.CheckCharacters = false;
settings.CloseInput = true;
using (XmlReader reader = XmlReader.Create(file, settings))
{
try
{
reader.MoveToContent();
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
Console.WriteLine("<{0}>", reader.Name);
break;
case XmlNodeType.Text:
Console.WriteLine("<{0}>", reader.Value);
break;
case XmlNodeType.CDATA:
Console.WriteLine("<![CDATA[{0}]]>", reader.Value);
break;
case XmlNodeType.ProcessingInstruction:
Console.WriteLine("<?{0} {1}?>", reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
Console.WriteLine("<!--{0}-->", reader.Value);
break;
case XmlNodeType.XmlDeclaration:
Console.WriteLine("<?xml version='1.0'?>");
break;
case XmlNodeType.Document:
break;
case XmlNodeType.DocumentType:
Console.WriteLine("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
break;
case XmlNodeType.EntityReference:
Console.WriteLine(reader.Name);
break;
case XmlNodeType.EndElement:
Console.WriteLine("</{0}>", reader.Name);
break;

}
}
}
catch (Exception exp)
{
Console.WriteLine(exp.Message);
}
finally
{
reader.Close();
}
}

For the attribute insied the node, especially, element type, use GetAttribute member fuction or using MovetoFirstAttribute or MovetoNextAttribute member function.

if (reader.AttributeCount > 0)
{
reader.MoveToFirstAttribute();
do
{
Console.WriteLine("attribut{0}:{1}", reader.Name, reader.Value);
} while (reader.MoveToNextAttribute());
}
XmlTextReader class is similar to XmlReader required user verification. It is recommanded to use the later.
XmlDocument class and XmlNode class
Use XmlDocument instance as the stream and XmlNode provides abundant manipulation. The good point of this easy to control, read and modify. But the defact is that it needs a lot of memory.
Here is usage of XmlDocument
static void XmlDocumentUsage(string file)
{
XmlDocument xml = new XmlDocument();
xml.Load(file);
XmlNode top = xml.DocumentElement;
XmlNodeList nodeList = top.SelectNodes("Item");
foreach (XmlNode node in nodeList)
{
RecursionShow(node, 0);
}
}

static void RecursionShow(XmlNode node, int level)
{
switch (node.NodeType)
{
case XmlNodeType.Element:
if (node.Attributes == null)
Console.WriteLine("{0}{1}", new string('\t', level), node.LocalName);
else
{
Console.WriteLine("{0}{1} {2}", new string('\t', level), node.LocalName, RetrieveAttribute(node.Attributes));
}
foreach (XmlNode subnode in node.ChildNodes)
{
RecursionShow(subnode, level++);
}
break;
case XmlNodeType.Text:
Console.WriteLine("{0}{1}", new string('\t', level + 1), node.Value.Trim());
break;
}
}

static string RetrieveAttribute(XmlAttributeCollection attrs)
{
string str = "";
foreach (XmlAttribute attr in attrs)
{
str += string.Format("{0}={1}, ", attr.Name, attr.Value);
}
return str;
}

xml file

<?xml version="1.0"?>
<!-- This is a sample XML document -->
<Items>
<Item value="1" type="2">Test with an entity:</Item>
<Item hha="3">
Test with a child element <more/> stuff
</Item>
<Item>Test with a CDATA section <![CDATA[<456>]]> def</Item>
<Item>Test with a char entity: &#65;</Item>
<!-- Fourteen chars in this element.-->
<Item>1234567890ABCD</Item>
</Items>

你可能感兴趣的:(xml)