XPath可以快速定位到Xml中的节点或者属性。XPath语法很简单,但是强大够用,它也是使用xslt的基础知识。
示例Xml:
100
this is a black cat
80
this is a white cat
80
this is a yellow cat
100
this is a black dog
80
this is a white dog
80
this is a yellow dog
XPath的语法:
1. XPath中的符号
符号 |
说明 |
示例 |
示例说明 |
/ |
表示从根节点开始选择 |
/pets |
选择根节点pets |
表示节点和子节点之间的间隔符 |
/pets/dog |
选择pets节点下的dog节点 |
|
//xx |
表示从整个xml文档中查找,而不考虑当前节点位置 |
//price |
选择文档中所有的price节点 |
. |
单个英文半角句点表示选择当前节点 |
/pets/. |
选择pets节点 |
.. |
双点,表示选择父节点 |
/pets/dog[0]/.. |
表示pets节点,也就是第一个dog节点的父节点 |
@xx |
表示选择属性 |
//dog/@color |
表示选择所有dog节点的color属性集合 |
[…] |
中括号表示选择条件,括号内为条件 |
//dog[@color=’white’] |
所有color为white的dog节点 |
//dog[/price<100] |
所有price字节点值小于100的dog节点 |
||
中括号内数字为节点索引,类似c#等语言中的数组,数组下标是从1开始的 |
//dog[1] |
第1个dog节点 |
|
//dog[last()] |
最后一个dog节点,last()是xPath内置函数 |
||
| |
单竖杠表示合并节点结合 |
//dog[@color=’white’] | //cat[@color=’white’] |
color属性为white的dog节点和color属性为white的cat节点 |
* |
星号表示任何名字的节点或者属性 |
//dog/* |
表示dog节点的所有子节点 |
//dog/@* |
表示dog节点的所有属性节点 |
关键字 |
说明 |
示例 |
示例说明 |
ancestor |
当前节点的父祖节点 |
ancestor::pig |
当前节点的祖先节点中的pig节点 |
ancestor-or-self |
当前节点以及其父祖节点 |
ancestor::pig |
|
attribute |
当前节点的所有属性 |
attribute::weight |
相当于@weight,attribute::和@是等价的 |
child |
当前节点的所有字节点 |
child::*[name()!=’price’] |
选择名字不是price的子节点 |
descendant |
子孙节点 |
descendant::*[@*] |
有属性的子孙节点 |
descendant-or-self |
子孙节点以及当前节点 |
descendant-or-self::* |
|
following |
Xml文档中当前节点之后的所有节点 |
following::* |
|
following-sibling |
当前节点的同父弟弟节点 |
following-sibling:: |
|
preceding |
Xml文档中当前节点之前的所有节点 |
preceding::* |
|
namespace |
选取当前节点的所有命名空间节点 |
namespace::* |
|
parent |
当前节点的父节点 |
parent:: |
相当于双点.. |
preceding-sibling |
当前节点之后的同父兄节点 |
preceding-sibling::* |
|
self |
当前节点 |
self::* |
相当于单点. |
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.XPath;
using System.Xml;
namespace UseXPathDotNet
{
class Program
{
static void Main(string[] args)
{
UseXPathWithXPathDocument();
UseXPathWithXmlDocument();
Console.Read();
}
static void UseXPathWithXmlDocument()
{
XmlDocument doc = new XmlDocument();
doc.Load("http://www.cnblogs.com/yukaizhao/rss");
//使用xPath选择需要的节点
XmlNodeList nodes = doc.SelectNodes("/rss/channel/item[position()<=10]");
foreach (XmlNode item in nodes)
{
string title = item.SelectSingleNode("title").InnerText;
string url = item.SelectSingleNode("link").InnerText;
Console.WriteLine("{0} = {1}", title, url);
}
}
static void UseXPathWithXPathDocument()
{
XPathDocument doc = new XPathDocument("http://www.cnblogs.com/yukaizhao/rss");
XPathNavigator xPathNav = doc.CreateNavigator();
//使用xPath取rss中最新的10条随笔
XPathNodeIterator nodeIterator = xPathNav.Select("/rss/channel/item[position()<=10]");
while (nodeIterator.MoveNext())
{
XPathNavigator itemNav = nodeIterator.Current;
string title = itemNav.SelectSingleNode("title").Value;
string url = itemNav.SelectSingleNode("link").Value;
Console.WriteLine("{0} = {1}",title,url);
}
}
}
}
XPath使用示例,请看下面的代码注释
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
namespace UseXPath1
{
class Program
{
static void Main(string[] args)
{
string xml = @"
100
this is a black cat
80
this is a white cat
110
this is a yellow cat
114
this is a black dog
80
this is a white dog
80
this is a yellow dog
8000
this is a white pig
";
using (StringReader rdr = new StringReader(xml))
{
XmlDocument doc = new XmlDocument();
doc.Load(rdr);
//取所有pets节点下的dog字节点
XmlNodeList nodeListAllDog = doc.SelectNodes("/pets/dog");
//所有的price节点
XmlNodeList allPriceNodes = doc.SelectNodes("//price");
//取最后一个price节点
XmlNode lastPriceNode = doc.SelectSingleNode("//price[last()]");
//用双点号取price节点的父节点
XmlNode lastPriceParentNode = lastPriceNode.SelectSingleNode("..");
//选择weight*count=40的所有动物,使用通配符*
XmlNodeList nodeList = doc.SelectNodes("/pets/*[@weight*@count=40]");
//选择除了pig之外的所有动物,使用name()函数返回节点名字
XmlNodeList animalsExceptPigNodes = doc.SelectNodes("/pets/*[name() != 'pig']");
//选择价格大于100而不是pig的动物
XmlNodeList priceGreaterThan100s = doc.SelectNodes("/pets/*[price div @weight >10 and name() != 'pig']");
foreach (XmlNode item in priceGreaterThan100s)
{
Console.WriteLine(item.OuterXml);
}
//选择第二个dog节点
XmlNode theSecondDogNode = doc.SelectSingleNode("//dog[position() = 2]");
//使用xpath ,axes 的 parent 取父节点
XmlNode parentNode = theSecondDogNode.SelectSingleNode("parent::*");
//使用xPath选择第二个dog节点前面的所有dog节点
XmlNodeList dogPresibling = theSecondDogNode.SelectNodes("preceding::dog");
//取文档的所有子孙节点price
XmlNodeList childrenNodes = doc.SelectNodes("descendant::price");
}
Console.Read();
}
}
}
本文转载自http://www.cnblogs.com/yukaizhao/archive/2011/07/25/xpath.html
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace XmlExample
{
class Program
{
static void Main(string[] args)
{
string xmlFilePath = @"X:\about.net\example\XmlExample\1.xml";
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
//使用xpath表达式选择文档中所有的student子节点
XmlNodeList studentNodeList = doc.SelectNodes("/students/student");
if (studentNodeList != null)
{
foreach (XmlNode studentNode in studentNodeList)
{
//通过Attributes获得属性名字为name的属性
string name = studentNode.Attributes["name"].Value;
Console.WriteLine("Student:" + name);
//通过SelectSingleNode方法获得当前节点下的courses子节点
XmlNode coursesNode = studentNode.SelectSingleNode("courses");
//通过ChildNodes属性获得courseNode的所有一级子节点
XmlNodeList courseNodeList = coursesNode.ChildNodes;
if (courseNodeList != null)
{
foreach (XmlNode courseNode in courseNodeList)
{
Console.Write("\t");
Console.Write(courseNode.Attributes["name"].Value);
Console.Write("老师评语");
//通过FirstNode属性可以获得课程节点的第一个子节点,LastNode可以获得最后一个子节点
XmlNode teacherCommentNode = courseNode.FirstChild;
//读取CData节点
XmlCDataSection cdata = (XmlCDataSection)teacherCommentNode.FirstChild;
Console.WriteLine(cdata.InnerText.Trim());
}
}
}
}
Console.Write("\r\nPress any key to continue....");
Console.Read();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace WriteXml
{
class Program
{
static void Main(string[] args)
{
XmlDocument xmlDoc = new XmlDocument();
//创建Xml声明部分,即
xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "yes");
//创建根节点
XmlNode rootNode = xmlDoc.CreateElement("students");
//创建student子节点
XmlNode studentNode = xmlDoc.CreateElement("student");
//创建一个属性
XmlAttribute nameAttribute = xmlDoc.CreateAttribute("name");
nameAttribute .Value = "张同学";
//xml节点附件属性
studentNode.Attributes.Append(nameAttribute);
//创建courses子节点
XmlNode coursesNode = xmlDoc.CreateElement("courses");
XmlNode courseNode1 = xmlDoc.CreateElement("course");
XmlAttribute courseNameAttr = xmlDoc.CreateAttribute("name");
courseNameAttr.Value = "语文";
courseNode1.Attributes.Append(courseNameAttr);
XmlNode teacherCommentNode = xmlDoc.CreateElement("teacherComment");
//创建Cdata块
XmlCDataSection cdata = xmlDoc.CreateCDataSection("这是语文老师的批注");
teacherCommentNode.AppendChild(cdata);
courseNode1.AppendChild(teacherCommentNode);
coursesNode.AppendChild(courseNode1);
//附加子节点
studentNode.AppendChild(coursesNode);
rootNode.AppendChild(studentNode);
//附加根节点
xmlDoc.AppendChild(rootNode);
//保存Xml文档
xmlDoc.Save(@"d:\test.xml");
Console.WriteLine("已保存Xml文档");
}
}
}
使用XmlDocument生成xml的要点在于使用xmlDocument的实例的CreateElement创建XmlNode或者通过CreateAttribute方法创建属性,并通过AppendChild方法附加xml节点,通过AppendAttribute附加Attribute到节点的属性集合。
XmlDocument和XElement在读取Xml时要将整个Xml文档放到内存中去操作,这样做操作简单,但是很费内存和IO(可能是磁盘IO或者网络IO);而在有些场景下我们必须考虑尽可能节省内存和IO的开销,这时候就该XmlReader和XmlWriter出场了。
XmlReader读取Xml需要通过Read()实例方法,不断读取Xml文档中的声明,节点开始,节点内容,节点结束,以及空白等等,直到文档结束,Read()方法返回false。
如下读取Xml内容实例代码和注释说明
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
namespace UseXmlReader
{
class Program
{
static void Main(string[] args)
{
//声明StringReader传入Xml文本,作为XmlReader.Create的参数
using (StringReader strRdr = new StringReader(@"
I'm a Cat
"))
{
//通过XmlReader.Create静态方法创建XmlReader实例
using (XmlReader rdr = XmlReader.Create(strRdr))
{
//循环Read方法直到文档结束
while (rdr.Read())
{
Console.WriteLine("rdr.NodeType = " + rdr.NodeType);
//如果是开始节点
if (rdr.NodeType == XmlNodeType.Element) {
//通过rdr.Name得到节点名
string elementName = rdr.Name;
Console.WriteLine(elementName + " element start");
if (elementName == "root") {
}
//读取到cat元素 这时rdr.Read()读取到的内容为
else if (elementName == "cat")
{
//可以通过中括号获得属性值
string colorVal = rdr["color"];
Console.WriteLine("\tcat's color is " + colorVal);
//读取到节点内文本内容
if(rdr.Read()) {
//通过rdr.Value获得文本内容
Console.WriteLine("\t cat said:" + rdr.Value);
}
}
}
else if (rdr.NodeType == XmlNodeType.EndElement)
{
//在节点结束时也可以通过rdr.Name获得节点名字
string elementName = rdr.Name;
Console.WriteLine(elementName + " element end");
}
}
}
}
Console.Read();
}
}
}
假定创建了XmlWriter的实例变量xmlWriter,下文中将使用此实例变量写Xml
1.如何使用XmlWriter写Xml文档声明
// WriteStartDocument方法可以接受一个bool参数(表示standalone,是否为独立文档)或者不指定参数standalone保持默认值
xmlWriter.WriteStartDocument(
false
|
true
);
|
注意在使用WriteStartDocument方法后最好调用xmlWrite.WriteEndDocument()方法来关闭所有可能未关闭标签
2.如何使用XmlWriter写xml节点以及属性
//写节点
xmlWriter.WriteStartElement(
"cat"
);
//给节点添加属性
xmlWriter.WriteAttributeString(
"color"
,
"white"
);
//给节点内部添加文本
xmlWriter.WriteString(
"I'm a cat"
);
xmlWriter.WriteEndElement();
|
或者通过WriteElementString(string,string)方法写xml节点同时写下节点值,如下
//通过WriteElementString可以添加一个节点同时添加节点内容
xmlWriter.WriteElementString(
"pig"
,
"pig is great"
);
|
3.如何写CData
xmlWriter.WriteStartElement(
"dog"
);
//写CData
xmlWriter.WriteCData(
"dog is dog"
);
xmlWriter.WriteEndElement();
|
4.如何使用XmlWriter添加注释
xmlWriter.WriteComment(
"this is an example writed by sedi "
);
|
5.如何设置XmlWriter的输出格式,解决输出UTF-16问题
设置xml输出格式,需要通过XmlWriterSettings类,如下代码
XmlWriterSettings settings =
new
XmlWriterSettings();
//要求缩进
settings.Indent =
true
;
//注意如果不设置encoding默认将输出utf-16
//注意这儿不能直接用Encoding.UTF8如果用Encoding.UTF8将在输出文本的最前面添加4个字节的非xml内容
settings.Encoding =
new
UTF8Encoding(
false
);
//设置换行符
settings.NewLineChars = Environment.NewLine;
|
完整的代码示例如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
namespace UseXmlWriter
{
class Program
{
static void Main(string[] args)
{
using (MemoryStream ms = new MemoryStream())
{
XmlWriterSettings settings = new XmlWriterSettings();
//要求缩进
settings.Indent = true;
//注意如果不设置encoding默认将输出utf-16
//注意这儿不能直接用Encoding.UTF8如果用Encoding.UTF8将在输出文本的最前面添加4个字节的非xml内容
settings.Encoding = new UTF8Encoding(false);
//设置换行符
settings.NewLineChars = Environment.NewLine;
using (XmlWriter xmlWriter = XmlWriter.Create(ms, settings))
{
//写xml文件开始
xmlWriter.WriteStartDocument(false);
//写根节点
xmlWriter.WriteStartElement("root");
//写字节点
xmlWriter.WriteStartElement("cat");
//给节点添加属性
xmlWriter.WriteAttributeString("color", "white");
//给节点内部添加文本
xmlWriter.WriteString("I'm a cat");
xmlWriter.WriteEndElement();
//通过WriteElementString可以添加一个节点同时添加节点内容
xmlWriter.WriteElementString("pig", "pig is great");
xmlWriter.WriteStartElement("dog");
//写CData
xmlWriter.WriteCData("dog is dog");
xmlWriter.WriteEndElement();
xmlWriter.WriteComment("this is an example writed by 玉开技术博客 http://www.cnblogs.com/yukaizhao ");
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
}
//将xml内容输出到控制台中
string xml = Encoding.UTF8.GetString(ms.ToArray());
Console.WriteLine(xml);
}
Console.Read();
}
}
}
class Program
{
static void Main(string[] args)
{
var xDoc = new XDocument(new XElement( "root",
new XElement("dog",
new XText("dog said black is a beautify color"),
new XAttribute("color", "black")),
new XElement("cat"),
new XElement("pig", "pig is great")));
//xDoc输出xml的encoding是系统默认编码,对于简体中文操作系统是gb2312
//默认是缩进格式化的xml,而无须格式化设置
xDoc.Save(Console.Out);
Console.Read();
}
}
dog said black is a beautify color
pig is great
class Program
{
static void Main(string[] args)
{
var xDoc = new XDocument(new XElement( "root",
new XElement("dog",
new XText("dog said black is a beautify color"),
new XAttribute("color", "black")),
new XElement("cat"),
new XElement("pig", "pig is great")));
//xDoc输出xml的encoding是系统默认编码,对于简体中文操作系统是gb2312
//默认是缩进格式化的xml,而无须格式化设置
xDoc.Save(Console.Out);
Console.WriteLine();
var query = from item in xDoc.Element( "root").Elements()
select new
{
TypeName = item.Name,
Saying = item.Value,
Color = item.Attribute("color") == null?(string)null:item.Attribute("color").Value
};
foreach (var item in query)
{
Console.WriteLine("{0} 's color is {1},{0} said {2}",item.TypeName,item.Color??"Unknown",item.Saying??"nothing");
}
Console.Read();
}
}
3. Linq to xml简单的应用
应用需求: 读取博客园的rss,然后在页面上输出最新的10篇博客信息
实现要点: 通过XDocument的Load静态方法载入Xml,通过linq查询最新10条数据
代码如下:
<%@ Page Language="C#" AutoEventWireup="true" %>
Linq to Xml 实例
-
<%#Eval("PostTime") %>"><%#Eval("Title") %>
Xml Schema的用途
1. 定义一个Xml文档中都有什么元素
2. 定义一个Xml文档中都会有什么属性
3. 定义某个节点的都有什么样的子节点,可以有多少个子节点,子节点出现的顺序
4. 定义元素或者属性的数据类型
5. 定义元素或者属性的默认值或者固定值
Xml Schema的根元素:
targetNamespace="http://www.w3schools.com" 表示文档中要定义的元素来自什么命名空间
xmlns="http://www.w3schools.com"表示此文档的默认命名空间是什么
elementFormDefault="qualified"> 表示要求xml文档的每一个元素都要有命名空间指定
……定义主体部分……
如何定义一个简单元素
name=”color” 表示要定义元素的名称
type=”xs:string” 表示要定义元素的数据类型
default=”red” 表示定义元素的默认值
fixed=”red”/> 表示要定义元素的固定值,此元素只可以取“red”值
以上定义了一个简单元素,元素实例:
如何定义一个属性
name=”birthday” 表示要定义属性的名字
type=”xs:date” 表示要定义属性的数据类型
default=”2001-01-11” 表示要定义属性的默认值
fixed=”2001-01-11” 表示要定义属性的固定值
use=”required”/> 表示此属性是否是必须指定的,即如果不指定就不符合Schema,默认没有use=”required”属性表示属性可有可无
如何定义元素或者属性值的限制
1.最大值最小值限制
2.枚举限制,指只能在指定的几个值中取值
3.模式(pattern)限制 ,指字符串的格式必须满足制定的匹配模式
例子 |
说明 |
|
表示只能在小写字母中取一个值 |
|
表示必须是三个大写字母 |
|
表示必须是三个字母,可以是大写或小写的 |
|
表示必须是xyz中的一个 |
|
表示数字的范围是0-99999 |
|
表示必须是0或者多个小写字符组成的序列 |
|
表示必须是多个字母。 |
|
表示是male或者female中的一个 |
|
表示必须是8个字母数字字符 |
4.字符串长度的限制
长度必须是8。
表示长度在5-8之间
6. 对于空白字符的限制
示例 |
说明 |
|
保留原样,表示xml处理器不会移除或者替换任何空白字符 |
|
指回车,换行,Tab都会被替换成空格处理 |
|
去掉多于一个空格,和html中处理方式相同 |
如何定义复杂类型
复杂类型是指定义元素中包含属性或者子元素的类型
1. 定义只包含子元素的复杂类型
2. 定义只包含属性的复杂类型
3. 定义只包含内容的复杂类型
4. 定义包含内容和子元素混合的复杂类型
以上定义对应的Xml
Dear Mr.
Your order
will be shipped on
5. 定义包含属性和子元素的复杂类型
使用指示器
在Xsd中的指示器包括
1. 顺序指示器
1) All
指示子元素可以以任何顺序出现,并且每一个元素都必须出现一次
2) Choice
指示子元素中可以出现一个或者另一个
3) Sequence
指示子元素必须按照顺序出现
2. 出现次数指示器minOccurs,maxOccurs
maxOccurs="10" minOccurs="0"/>
3. 组指示器(group Indicators)
用来定义相关的一组元素
用来定义一组相关的属性
Any关键字
表示可以有任意元素
anyAttribute关键字
substitutionGroup关键字
表示某一个元素和另一个替代元素定义相同
文中的例子都来自w3school.
class Program
{
static void Main(string[] args)
{
int i = 10;
//声明Xml序列化对象实例serializer
XmlSerializer serializer = new XmlSerializer(typeof(int));
//执行序列化并将序列化结果输出到控制台
serializer.Serialize(Console.Out, i);
Console.Read();
}
}
10
可以将上述序列化的xml进行反序列化,如下代码
static void Main(string[] args)
{
using (StringReader rdr = new StringReader(@"
10 "))
{
//声明序列化对象实例serializer
XmlSerializer serializer = new XmlSerializer(typeof(int));
//反序列化,并将反序列化结果值赋给变量i
int i = (int)serializer.Deserialize(rdr);
//输出反序列化结果
Console.WriteLine("i = " + i);
Console.Read();
}
}
以上代码用最简单的方式说明了xml序列化和反序列化的过程,.Net系统类库为我们做了大量的工作,序列化和反序列化都非常简单。但是在现实中业务需求往往比较复杂,不可能只简单的序列化一个int变量,显示中我们需要对复杂类型进行可控制的序列化。
自定义对象的Xml序列化:
System.Xml.Serialization命名空间中有一系列的特性类,用来控制复杂类型序列化的控制。例如XmlElementAttribute、XmlAttributeAttribute、XmlArrayAttribute、XmlArrayItemAttribute、XmlRootAttribute等等。
看一个小例子,有一个自定义类Cat,Cat类有三个属性分别为Color,Saying,Speed。
namespace UseXmlSerialization
{
class Program
{
static void Main(string[] args)
{
//声明一个猫咪对象
var c = new Cat { Color = "White", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };
//序列化这个对象
XmlSerializer serializer = new XmlSerializer(typeof(Cat));
//将对象序列化输出到控制台
serializer.Serialize(Console.Out, c);
Console.Read();
}
}
[XmlRoot("cat")]
public class Cat
{
//定义Color属性的序列化为cat节点的属性
[XmlAttribute("color")]
public string Color { get; set; }
//要求不序列化Speed属性
[XmlIgnore]
public int Speed { get; set; }
//设置Saying属性序列化为Xml子元素
[XmlElement("saying")]
public string Saying { get; set; }
}
}
可以使用XmlElement指定属性序列化为子节点(默认情况会序列化为子节点);或者使用XmlAttribute特性制定属性序列化为Xml节点的属性;还可以通过XmlIgnore特性修饰要求序列化程序不序列化修饰属性。
对象数组的Xml序列化:
数组的Xml序列化需要使用XmlArrayAttribute和XmlArrayItemAttribute;XmlArrayAttribute指定数组元素的Xml节点名,XmlArrayItemAttribute指定数组元素的Xml节点名。
如下代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace UseXmlSerialization
{
class Program
{
static void Main(string[] args)
{
//声明一个猫咪对象
var cWhite = new Cat { Color = "White", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };
var cBlack = new Cat { Color = "Black", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" };
CatCollection cc = new CatCollection { Cats = new Cat[] { cWhite,cBlack} };
//序列化这个对象
XmlSerializer serializer = new XmlSerializer(typeof(CatCollection));
//将对象序列化输出到控制台
serializer.Serialize(Console.Out, cc);
Console.Read();
}
}
[XmlRoot("cats")]
public class CatCollection
{
[XmlArray("items"),XmlArrayItem("item")]
public Cat[] Cats { get; set; }
}
[XmlRoot("cat")]
public class Cat
{
//定义Color属性的序列化为cat节点的属性
[XmlAttribute("color")]
public string Color { get; set; }
//要求不序列化Speed属性
[XmlIgnore]
public int Speed { get; set; }
//设置Saying属性序列化为Xml子元素
[XmlElement("saying")]
public string Saying { get; set; }
}
}
以上代码将输出:
-
White or black, so long as the cat can catch mice, it is a good
cat
-
White or black, so long as the cat can catch mice, it is a good
cat
XmlSerializer内存泄漏问题:
多谢chenlulouis,仔细看了下msdn,确实存在泄漏的情况,msdn说明如下:
动态生成的程序集
为了提高性能,XML 序列化基础结构将动态生成程序集,以序列化和反序列化指定类型。此基础结构将查找并重复使用这些程序集。此行为仅在使用以下构造函数时发生:
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
如果使用任何其他构造函数,则会生成同一程序集的多个版本,且绝不会被卸载,这将导致内存泄漏和性能降低。最简单的解决方案是使用先前提到的两个构造函数的其中一个。否则,必须在 Hashtable 中缓存程序集,如以下示例中所示。
也就是说我们在使用XmlSerializer序列化,初始化XmlSerializer对象时最好使用下面两个构造函数否则会引起内存泄漏。
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
XSL即可扩展的样式表文件。 可以格式化xml的显示,也可以将xml转换成需要的另一种格式。
学习XSL必须熟悉XPath。XSL和XPath一样简单强大,容易学习。
1. XSL既然可以格式化xml的显示样式,我们先来看如何在xml中引用xsl文件
如下代码示例:
只需在xml文件的文档声明后面添加即可
2. XSL的格式
XSL也是一个标准的xml文件,它以xml文档声明开始,根元素必须是xsl:styleshee,同时根元素必须有version属性指定xsl的版本,和xmlns:xsl=” http://www.w3.org/1999/XSL/Transform”指定xsl命名空间,如下示例
3. Xsl要点 如下示例xml
100
this is a blue pig
80
this is a red cat
80
this is a green dog
80
this is a green cat
100
this is a blue dog
80
this is a red dog
1) xsl:template定义匹配节点的转换模板,属性match=”xpath expression”用来定义模板匹配的元素
如下定义匹配根节点的模板
2) xsl:for-each循环显示select=”xpath expression”选择节点的转换 (类似编程语言中的foreach语句),
如下示例,选择了pets下面的子元素,并循环显示子元素的几点名字:
3) xsl:if 元素条件显示节点(类似编程语言中的if语句)注意小于号大于号要分别用<和>替代
its weight is less than 10 km
4) xsl:choose 多分支条件显示 (类似编程语言中的switch语句)
this is a pig
this is not a pig
5) xsl:value-of 显示选择节点或者属性的值
选择子节点price
选择属性weight
6) xsl:attribute 构造xml节点的属性
用来向节点添加属性,例如:
将输出
7) xsl:apply-templates 应用模板
如果xml文件结构比较复杂,可以定义多个template,然后使用
请看下面示例xslt文件pets-templates.xsl
lovely pets
lovely pets
-
http://estar-tv.com/images/comprofiler/gallery/dog.gif
http://www.icosky.com/icon/thumbnails/Animal/Farm/Pig%20Icon.jpg
http://farm1.static.flickr.com/14/buddyicons/[email protected]?1143660418
Courier
said: " "
weight:
its weight is less than 10 km
lovely pets
lovely pets
-
http://estar-tv.com/images/comprofiler/gallery/dog.gif
http://www.icosky.com/icon/thumbnails/Animal/Farm/Pig%20Icon.jpg
http://farm1.static.flickr.com/14/buddyicons/[email protected]?1143660418
Courier
said: " "
weight:
its weight is less than 10 km
完整示例文件 pets-templates.xsl:
lovely pets
lovely pets
http://estar-tv.com/images/comprofiler/gallery/dog.gif
Courier
dog
said: " "
weight:
its weight is less than 10 km
http://www.icosky.com/icon/thumbnails/Animal/Farm/Pig%20Icon.jpg
Courier
pig
said: " "
weight:
its weight is less than 10 km
http://farm1.static.flickr.com/14/buddyicons/[email protected]?1143660418
Courier
cat
said: " "
weight:
its weight is less than 10 km
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
namespace UseXslt
{
class Program
{
static void Main(string[] args)
{
//声明XslTransform类实例
System.Xml.Xsl.XslCompiledTransform trans = new System.Xml.Xsl.XslCompiledTransform();
string xsltFile = @"X:\about.net\System.Xml\example\pets.xsl";
using (StreamReader rdr = new StreamReader(xsltFile))
{
using (XmlReader xmlRdr = XmlReader.Create(rdr))
{
//载入xsl文件
trans.Load(xmlRdr);
}
}
string inputFile = @"X:\about.net\System.Xml\example\pets.xml";
string outputFile = @"X:\about.net\System.Xml\example\pets-out.htm";
//转化源文件输出到输出文件outputFile
trans.Transform(inputFile, outputFile);
}
}
}
有一点需要注意,使用XslCompiledTransform转换出来的文件,是一个html格式的,这个类会自动在html的head标签中添加一个未关闭的meta标签 ;微软帮我们想的太多了。
Xslt还可以指定参数,定义变量,有关这些方面请查看相关文档。