C#解析与创建XML数据
简介
XML教程参考链接:https://www.w3school.com.cn/xml/index.asp
XML 使用简单的具有自我描述性的语法:
<?xml version="1.0" encoding="ISO-8859-1"?> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
参考文档:https://blog.csdn.net/u010445297/article/details/61202161
1.使用XmlDocument.
参考链接 https://www.cnblogs.com/sayhallotoyou/p/4251664.html
使用XmlDocument是一种基于文档结构模型的方式来读取XML文件.在XML文件中,我们可以把XML看作是由文档声明(Declare),元素(Element),属性(Attribute),文本(Text)等构成的一个树.最开始的一个结点叫作根结点,每个结点都可以有自己的子结点.得到一个结点后,可以通过一系列属性或方法得到这个结点的值或其它的一些属性.例如:
1: xn 代表一个结点
2: xn.Name;//这个结点的名称
3: xn.Value;//这个结点的值
4: xn.ChildNodes;//这个结点的所有子结点
5: xn.ParentNode;//这个结点的父结点
6: .......
<bookstore> <book Type="必修课" ISBN="7-111-19149-2"> <title>数据结构</title> <author>严蔚敏</author> <price>30.00</price> </book> </bookstore>
//创建XML文件数据
XmlDocument xmlDoc = new XmlDocument(); //xmlDoc.Load(path); xmlDoc.LoadXml("<bookstore></bookstore>");//用这句话,会把以前的数据全部覆盖掉,只有你增加的数据 XmlNode root = xmlDoc.SelectSingleNode("bookstore"); //创建一个结点,并设置结点的属性: XmlElement xelKey = xmlDoc.CreateElement("book"); XmlAttribute xelType = xmlDoc.CreateAttribute("Type"); xelType.InnerText = "必修课"; xelKey.SetAttributeNode(xelType); xelType = xmlDoc.CreateAttribute("ISBN"); xelType.InnerText = "7-111-19149-2"; xelKey.SetAttributeNode(xelType); XmlElement xelAuthor = xmlDoc.CreateElement("title"); xelAuthor.InnerText = "数据结构"; xelKey.AppendChild(xelAuthor); xelAuthor = xmlDoc.CreateElement("author"); xelAuthor.InnerText = "严蔚敏"; xelKey.AppendChild(xelAuthor); xelAuthor = xmlDoc.CreateElement("price"); xelAuthor.InnerText = "30.00"; xelKey.AppendChild(xelAuthor); root.AppendChild(xelKey); xmlDoc.Save(path);
/// <summary>
/// 向已有的文件上追加数据
/// </summary>
/// <param name="path"></param>
private static void AppendXmlNode(string path)
{
//加载文件并选出要结点:
XmlDocument xmlDoc = new XmlDocument();//创建一个xml文档
xmlDoc.Load(path);
XmlNode root = xmlDoc.SelectSingleNode("bookstore");
//创建一个结点,并设置结点的属性:
XmlElement xelKey = xmlDoc.CreateElement("book");
XmlAttribute xelType = xmlDoc.CreateAttribute("Type");
xelType.InnerText = "adfdst";
xelKey.SetAttributeNode(xelType);
//创建子结点:
XmlElement xelAuthor = xmlDoc.CreateElement("author");
xelAuthor.InnerText = "李四";
xelKey.AppendChild(xelAuthor);
//最后把book结点挂接在要结点上,并保存整个文件:
root.AppendChild(xelKey);
xmlDoc.Save(path);
}
private static void ReadXml(string path)
{
XmlDocument xmlDoc = new XmlDocument();//创建一个xml文档
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;//忽略文档里面的注释
XmlReader reader = XmlReader.Create(path, settings);
xmlDoc.Load(reader);
//xmlDoc.Load(@"C:\Users\Administrator\Desktop\test.xml"); 这种方式会将注释也读出来
//调用SelectSingleNode得到指定的结点,通过GetAttribute得到具体的属性值.
//得到根节点bookstore
XmlNode xn = xmlDoc.SelectSingleNode("bookstore");
// 得到根节点的所有子节点
List<BookModel> bookModeList = new List<BookModel>();
XmlNodeList xnl = xn.ChildNodes;
foreach (XmlElement xn1 in xnl)
{
BookModel bookModel = new BookModel();
// 将节点转换为元素,便于得到节点的属性值
XmlElement xe = xn1;
// 得到Type和ISBN两个属性的属性值
bookModel.BookISBN = xe.GetAttribute("ISBN").ToString();
bookModel.BookType = xe.GetAttribute("Type").ToString();
// 得到Book节点的所有子节点
XmlNodeList xnl0 = xe.ChildNodes;
bookModel.BookName = xnl0.Item(0).InnerText;
bookModel.BookAuthor = xnl0.Item(1).InnerText;
bookModel.BookPrice = Convert.ToDouble(xnl0.Item(2).InnerText);
bookModeList.Add(bookModel);
}
reader.Close();
foreach (var item in bookModeList)
{
Console.WriteLine(item.ToString());
}
Console.Read();
}
class BookModel
{
public string BookType { get; set; }
/// <summary>
/// 书所对应的ISBN号
/// </summary>
public string BookISBN { get; set; }
public string BookName { get; set; }
public string BookAuthor { get; set; }
public double BookPrice { get; set; }
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("类型:"+ BookType+"\t");
stringBuilder.Append("ISBN:"+BookISBN+"\t");
stringBuilder.Append("作者:"+ BookAuthor+"\t");
stringBuilder.Append("价格:"+ BookPrice);
return stringBuilder.ToString();
}
}
序列化与反序列化
XML 序列化标记 IExtensibleDataObject [DataContract]
[XmlRoot(ElementName = "GuaHaoYJS_OUT")] [Serializable] public class GuaHaoYJS_OUT { [XmlElement(ElementName = "ERRNO")] public string ERRNO { set; get; } [XmlArray("ITEMS"), XmlArrayItem("ITEM")] public ITEM[] ITEMS { set; get; } } [XmlRoot("ITEM")] public class ITEM { [XmlElement(ElementName = "SHOUFEIXMZL")] public string SHOUFEIXMZL { set; get; } }
public static void XmlSerializes() { XmlSerializer xmlSerializer = new XmlSerializer(typeof(AcadRegConfig)); TextWriter writer = new StreamWriter("DataFile.xml"); AcadRegConfig regConfig = new AcadRegConfig() { Description = "我的", MaxVersion = 19.1M, MinVersion = "16.0", Name = "李四", Path = "Main", RegisterName = "/Net40" }; xmlSerializer.Serialize(writer, regConfig); writer.Close(); } public static void XmlDeserializes() { XmlSerializer xmlSerializer = new XmlSerializer(typeof(AcadRegConfig)); //xmlSerializer.UnknownNode += serializer_UnknownNode; //xmlSerializer.UnknownAttribute += serializer_UnknownAttribute; TextReader reader = new StreamReader("DataFile.xml"); var regConfig = xmlSerializer.Deserialize(reader); reader.Close(); Console.WriteLine(((AcadRegConfig)regConfig).ToString()); }
public static void Serialize() { AcadRegConfig regConfig = new AcadRegConfig() { Description = "我的", MaxVersion = 19.1M, MinVersion = "16.0", Name = "李四", Path = "Main", RegisterName = "/Net40" }; // To serialize the hashtable and its key/value pairs, // you must first open a stream for writing. // In this case, use a file stream. FileStream fs = new FileStream("DataFile.xml", FileMode.Create); // Construct a BinaryFormatter and use it to serialize the data to the stream. BinaryFormatter formatter = new BinaryFormatter(); try { formatter.Serialize(fs, regConfig); } catch (SerializationException e) { Console.WriteLine("Failed to serialize. Reason: " + e.Message); throw; } finally { fs.Close(); } } public static void Deserialize() { // Declare the hashtable reference. AcadRegConfig regConfig = null; // Open the file containing the data that you want to deserialize. FileStream fs = new FileStream("DataFile.xml", FileMode.Open); try { BinaryFormatter formatter = new BinaryFormatter(); // Deserialize the hashtable from the file and // assign the reference to the local variable. regConfig = (AcadRegConfig)formatter.Deserialize(fs); } catch (SerializationException e) { Console.WriteLine("Failed to deserialize. Reason: " + e.Message); throw; } finally { fs.Close(); } // To prove that the table deserialized correctly, // display the key/value pairs. Console.WriteLine(regConfig.ToString()); }
XML 后台创建与保存
//<Test> // <Book attribute="red">English book</Book> //</Test> XmlDocument xml = new XmlDocument();//创建一个xml文档 XmlElement element = xml.CreateElement("Book");//生成元素 element.InnerText = "English book"; XmlAttribute attribute = xml.CreateAttribute("attribute");//生成属性 attribute.Value = "red"; element.SetAttributeNode(attribute);//设置元素属性 XmlNode node = xml.CreateNode(XmlNodeType.Element, "Test", "");//生成节点 node.AppendChild(element); xml.AppendChild(node); xml.Save(@"C:\Users\Administrator\Desktop\test.xml");//保存文件
选择指定节点
XML内容如下
<?xml version="1.0" encoding="utf-8" ?> <Ribbon> <RibbonTab Name="菜单" Title="456"> <RibbonPanel Name="工具" Title="123"> <Button Name="设置" Title="456"/> <Button Name="点击" Title="456"/> <Button Name="编辑" Title="456"/> <Button Name="修改" Title="456"/> </RibbonPanel> <RibbonPanel Name="颜色" Title="123"> <Button Name="设置" Title="456"/> <Button Name="编辑" Title="456"/> <Button Name="修改" Title="456"/> </RibbonPanel> </RibbonTab> <RibbonTab Name="其它" Title="456"> <RibbonPanel Name="工具" Title="123"> <Button Name="设置" Title="456"/> <Button Name="点击" Title="456"/> <Button Name="编辑" Title="456"/> <Button Name="修改" Title="456"/> </RibbonPanel> </RibbonTab> </Ribbon>
1、定位到指定节点
//节点/孩子节点[条件]
var xmlNode = xmlDocument.SelectSingleNode("//Ribbon/RibbonTab[@Name='其它']");
var xmlNode = xmlDocument.SelectSingleNode("//Ribbon/RibbonTab[@Name='其它']//RibbonPanel");
2、选择并遍历节点
var xmlNode = xmlDocument.LastChild; xmlNode.SelectNodes("//RibbonPanel").Foreach<XmlNode>(node => Console.WriteLine(node?.InnerXml));
将表达式更改为 "//RibbonTab/RibbonPanel" 输出相同结果
或者使用下列方式也输出相同结果
xmlDocument.SelectNodes("//RibbonTab/RibbonPanel").Foreach<XmlNode>(node => Console.WriteLine(node?.InnerXml));
XPath表达式
实例文档
<?xml version="1.0" encoding="ISO-8859-1"?> <bookstore> <book> <title lang="eng">Harry Potter</title> <price>29.99</price> </book> <book> <title lang="eng">Learning XML</title> <price>39.95</price> </book> </bookstore>
在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档节点(或称为根节点)。
XPath 术语
节点(Node)
在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。
XPath 语法
谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在方括号中。
XPath Axes(轴)
步(step)包括:
- 轴(axis)
- 定义所选节点与当前节点之间的树关系
- 节点测试(node-test)
- 识别某个轴内部的节点
- 零个或者更多谓语(predicate)
- 更深入地提炼所选的节点集
步的语法:
轴名称::节点测试[谓语]
XPath 运算符
命名空间
命名空间(Namespace),对于每一套特定应用的DTD,给它一个独一无二的标志来代表,如果在XML中使用DTD中定义的元素,需将DTD的标志和元素名,属性连在一起使用,相当于指明了元素来自什么地方,这样就不会同其他同名元素混淆了(有点类似Java中包的作用,给它取个全名)。在XML中,采用现成的,在全球范围唯一的“域名”作为Namespace,即URL作为XML的Namespace。
命名空间允许我们在一个文档中结合不同的元素和属性定义,并指明这些元素和属性的定义来自那里。
命名空间的语法如下:
xmlns:[prefix]=”[url of name]”
其中“xmlns:”是必须的属性。“prefix”是命名空间的别名,它的值不能为xml。
<sample xmlns:ins=”http://www.lsmx.net.ac”> <ins:batch-list> <ins:batch>Evening Batch</ins:batch> </ins:batch-list> </sample>
值得注意的是batch-list,batch等标记必须在" http://www.lsmx.net.ac"中定义,别名为ins。注意在使用前必须先声明命名空间,在使用时别忘了“:”。
一,默认Namespace xmlns=”[url of namespace]”
二,指定了父元素的命名空间,子元素希望用自己的命名空间,可以在子元素中指定命名空间的别名。
三,属性也可以有自己的命名空间。