XmlReader 通过游标在文档中移动,当目标内容被找到时会把游标停在相应的位置。不是靠事件触发,而是依赖于开发人员通过制定功能来精确定位目标内容。
1.获取元素属性和数据
需要处理的xml文档:设置XML文件属性Copy to Output Directory的值为Copy If Newer,这会被复制到和应用程序相同的文件夹下,更容易定位。
<People xmlns="http://wrox.com/namespaces/BeginningXml/People">
<Person bornDate="1874-11-30" diedDate="1965-01-24">
<Name>Winston Churchill</Name>
<Description>
Winston Churchill was a mid 20th century British politician who
became famous as Prime Minister during the Second World War.
</Description>
</Person>
<Person bornDate="1917-11-19" diedDate="1984-10-31">
<Name>Indira Gandhi</Name>
<Description>
Indira Gandhi was India's first female prime minister and was
assassinated in 1984.
</Description>
</Person>
<Person bornDate="1917-05-29" diedDate="1963-11-22">
<Name>John F. Kennedy</Name>
<Description>
JFK, as he was affectionately known, was a United States president
who was assassinated in Dallas, Texas.
</Description>
</Person>
</People>
获取元素和属性:(c#代码)
static void Main(string[] args)
{
string xmlUri = "People.xml";
XmlReader reader = DisplayRootElement(xmlUri); //显示文档的根元素,并返回当前根节点
reader = DisplayPeopleWithDates(reader); //基本导航功能的使用,并读取元素和属性中的值
Console.ReadKey();
}
private static XmlReader DisplayRootElement(string uri)
{
XmlReader reader = XmlReader.Create(uri); //使用XmlReader类中的静态工厂方法创建一个XmlReader
reader.MoveToContent(); //将reader对象的游标定位到文档的根元素上
string rootElementName = reader.Name;
Console.WriteLine("Root element name is: {0}", rootElementName);
return reader;
}
private static XmlReader DisplayPeopleWithDates(XmlReader reader)
{
while (reader.Read()) //Read()函数的作用是在XML文档内的元素箭移动
{
if(reader.NodeType==XmlNodeType.Element && reader.Name=="Person")
{
DateTime bornDate = new DateTime();
DateTime diedDate = new DateTime();
var personName = string.Empty;
while(reader.MoveToNextAttribute())
{
switch (reader.Name)
{
case "bornDate":
bornDate = reader.ReadContentAsDateTime();
break;
case "diedDate":
diedDate = reader.ReadContentAsDateTime();
break;
}
}
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Name")
{
personName = reader.ReadElementContentAsString();
break;
}
}
Console.WriteLine("{0} was born in {1} and died in {2}", personName,bornDate.ToShortDateString(),diedDate.ToShortDateString());
}
}
return reader;
}
执行结果如下:
2. 使用XmlSchemaSet根据XML Schema验证XML文档
添加XML Schema文档:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://wrox.com/namespaces/BeginningXml/People" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="People">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Person">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Description" type="xs:string" />
</xs:sequence>
<xs:attribute name="bornDate" type="xs:date" use="required" />
<xs:attribute name="diedDate" type="xs:date" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
C#代码:
static void Main(string[] args)
{
string xmlUri = "PeopleWithNamespace.xml";
string targetNamespace = "http://wrox.com/namespaces/BeginningXml/People";
string schemaUri = "PeopleWithNamespace.xsd";
ValidateDocument(xmlUri, targetNamespace, schemaUri);
Console.ReadKey();
}
private static void ValidateDocument(string uri, string targetNamespace, string schemaUri)
{
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.Add(targetNamespace, schemaUri);
XmlReaderSettings setting = new XmlReaderSettings();
setting.IgnoreComments = true; //忽略所有注释
setting.ValidationType = ValidationType.Schema;
setting.Schemas = schemaSet;
setting.ValidationEventHandler += ValidationCallbace; //验证错误被调用的方法
var reader = XmlReader.Create(uri, setting);
while (reader.Read()) ;
#region 输出XML中元素个数
//int i = 0;
//while (reader.Read())
//{
// if (reader.NodeType == XmlNodeType.Element)
// {
// i++;
// Console.WriteLine(i);
// }
//}
#endregion
Console.WriteLine("Validation complete.");
}
private static void ValidationCallbace(object sender, ValidationEventArgs e)
{
Console.WriteLine("Validation Error;{0}\n\t Line number {1}, position{2}.",
e.Message,e.Exception.LineNumber,e.Exception.LinePosition);
}
执行结果如下:
若XML文档不符合XML Schema时,执行结果如下:
3. 使用XmlSecureResolver类,对允许访问的域名进行限制。
3.1 首先定义一个System.Net.WebPermission变量:引用命名空间 using System.Net;
WebPermission permission = new WebPermission(System.Security.Permissions.PermissionState.None);
3.2 为其添加两个指定的URL
permission.AddPermission(NetworkAccess.Connect, "http://myWebServer.coom");
permission.AddPermission(NetworkAccess.Connect, "http://myDataServer.coom");
3.3 将这个WebPermission添加到一个PermissionSet中,这可以灵活的配置不同的访问权限,引入命名空间 using System.Security;
PermissionSet permissionSet = new PermissionSet(System.Security.Permissions.PermissionState.None);
permissionSet.AddPermission(permission);
3.4 最后创建XmlSecureResolver,并将PermissionSet赋予它
XmlSecureResolver resolver = new XmlSecureResolver(new XmlUrlResolver(), permissionSet);
3.5 Resolver的使用
XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = resolver;
XmlReader reader = XmlReader.Create(xmlUir, settings);