[Visual Basic, C#, JScript] 下面的示例验证一个 XML 文件,并生成相应的错误或警告。
[Visual Basic]
Imports System
Imports System.IO
Imports System.Xml
Imports System.Xml.Schema
public class Sample
public shared sub Main ()
'Load the schema collection.
Dim xsc as XmlSchemaCollection = new XmlSchemaCollection()
xsc.Add("urn:bookstore-schema", "books.xsd")
'Validate the file using the schema stored in the collection.
'Any elements belonging to the namespace "urn:cd-schema" generate
'a warning since the there is no schema matching that namespace.
Validate("store.xml", xsc)
end sub
private shared sub Validate(filename as String, xsc as XmlSchemaCollection)
Console.WriteLine()
Console.WriteLine("Validating XML file {0}...", filename.ToString())
Dim reader as XmlTextReader = new XmlTextReader (filename)
Dim vreader as XmlValidatingReader =new XmlValidatingReader (reader)
vreader.ValidationType = ValidationType.Schema
vreader.Schemas.Add(xsc)
'Set the validation event handler.
AddHandler vreader.ValidationEventHandler, AddressOf ValidationCallBack
'Read the XML data.
while (vreader.Read())
end while
'Close the reader.
vreader.Close()
end sub
'Display any warnings or errors.
public shared sub ValidationCallBack (sender as object, args as ValidationEventArgs)
if (args.Severity=XmlSeverityType.Warning)
Console.WriteLine(" Warning: Matching schema not found. No validation occurred." + args.Message)
else
Console.WriteLine(" Validation error: " + args.Message)
end if
end sub
end class
[C#]
using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
public class Sample
{
public static void Main ()
{
//Load the schema collection.
XmlSchemaCollection xsc = new XmlSchemaCollection();
xsc.Add("urn:bookstore-schema", "books.xsd");
//Validate the file using the schema stored in the collection.
//Any elements belonging to the namespace "urn:cd-schema" generate
//a warning since the there is no schema matching that namespace.
Validate("store.xml", xsc);
}
private static void Validate(String filename, XmlSchemaCollection xsc)
{
Console.WriteLine();
Console.WriteLine("\r\nValidating XML file {0}...", filename.ToString());
XmlTextReader reader = new XmlTextReader (filename);
XmlValidatingReader vreader=new XmlValidatingReader (reader);
vreader.ValidationType = ValidationType.Schema;
vreader.Schemas.Add(xsc);
//Set the validation event handler.
vreader.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
//Read the XML data.
while (vreader.Read()){}
//Close the reader.
vreader.Close();
}
//Display any warnings or errors.
public static void ValidationCallBack (object sender, ValidationEventArgs args)
{
if (args.Severity==XmlSeverityType.Warning)
Console.WriteLine("\tWarning: Matching schema not found. No validation occurred." + args.Message);
else
Console.WriteLine("\tValidation error: " + args.Message);
}
}
[JScript]
import System
import System.IO
import System.Xml
import System.Xml.Schema
public class Sample
{
public static function Main ()
{
//Load the schema collection.
var xsc : XmlSchemaCollection = new XmlSchemaCollection();
xsc.Add("urn:bookstore-schema", "books.xsd");
//Validate the file using the schema stored in the collection.
//Any elements belonging to the namespace "urn:cd-schema" generate
//a warning since the there is no schema matching that namespace.
Validate("store.xml", xsc);
}
private static function Validate(filename : String, xsc : XmlSchemaCollection)
{
Console.WriteLine();
Console.WriteLine("\r\nValidating XML file {0}...", filename.ToString());
var reader : XmlTextReader = new XmlTextReader (filename);
var vreader : XmlValidatingReader = new XmlValidatingReader (reader);
vreader.ValidationType = ValidationType.Schema;
vreader.Schemas.Add(xsc);
//Set the validation event handler.
vreader.add_ValidationEventHandler(ValidationCallBack);
//Read the XML data.
while (vreader.Read()){}
//Close the reader.
vreader.Close();
}
//Display any warnings or errors.
public static function ValidationCallBack (sender, args : ValidationEventArgs)
{
if (args.Severity==XmlSeverityType.Warning)
Console.WriteLine("\tWarning: Matching schema not found. No validation occurred." + args.Message);
else
Console.WriteLine("\tValidation error: " + args.Message);
}
}
[Visual Basic, C#, JScript] 前面的示例使用下列输入文件。
[Visual Basic, C#, JScript] store.xml
<?xml version='1.0'?>
<bookstore xmlns="urn:bookstore-schema" xmlns:cd="urn:cd-schema">
<book genre="novel">
<title>The Confidence Man</title>
<price>11.99</price>
</book>
<cd:cd>
<title>Americana</title>
<cd:artist>Offspring</cd:artist>
<price>16.95</price>
</cd:cd>
</bookstore>
books.xsd
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="urn:bookstore-schema"
elementFormDefault="qualified"
targetNamespace="urn:bookstore-schema">
<xsd:element name="bookstore" type="bookstoreType"/>
<xsd:complexType name="bookstoreType">
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="book" type="bookType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="bookType">
<xsd:sequence>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="authorName"/>
<xsd:element name="price" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="genre" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="authorName">
<xsd:sequence>
<xsd:element name="first-name" type="xsd:string"/>
<xsd:element name="last-name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
2009年12月28日星期一
[+/-] |
用schema验证一个 XML文件,并生成相应的错误或警告 |
[+/-] |
XML Schema 中 全局声明和局部声明 |
全局声明和局部声明
直接在xs:schema元素下声明的元素和属性是全局的,这些元素和属性可以通过xs:element和xs :attribute元素的ref属性来引用。我们看例4-14。
例4-14
book.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="book" type="bookType"/>
<xs:element name="title" type="xs:token"/>
<xs:element name="author" type="xs:token"/>
<xs:attribute name="isbn" type="xs:token"/>
<xs:complexType name="bookType">
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="author"/>
</xs:sequence>
<xs:attribute ref="isbn"/>
</xs:complexType>
</xs:schema>
在例4-14中,声明的元素book、title和author,以及属性isbn都是全局的,在bookType类型定义中,我们通过xs:element和xs :attribute元素的ref属性来引用全局声明的元素和属性。
要注意的是:(1)全局声明的元素和属性的名称在模式中必须是唯一的。(2)在全局声明中不能使用ref属性。(3)全局声明的元素在实例文档中可以作为根元素出现。
在复杂类型定义内部声明的元素和属性是局部的,由于简单类型不能有子元素和属性,所以局部元素声明和局部属性声明不能出现在简单类型定义内部。我们将例4-14中的title、author元素,以及isbn属性改为局部声明,如例4-15所示。
例4-15
book2.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="book" type="bookType"/>
<xs:complexType name="bookType">
<xs:sequence>
<xs:element name="title" type="xs:token"/>
<xs:element name="author" type="xs:token"/>
</xs:sequence>
<xs:attribute name="isbn" type="xs:token"/>
</xs:complexType>
</xs:schema>
现在title、author元素和isbn属性都是在bookType类型定义内部声明的,这些局部声明只能在bookType类型定义内部使用。
如果模式文档中所有声明的元素名都是唯一的,那么可以使用全局声明,然而,当有两个同名但具有不同类型的元素时,你就只能使用局部声明了。例如,你可以声明一个局部元素title,它有xs:token类型,而且它是book元素的子元素,在同一个模式文档中,你还可以声明一个局部元素title,它可带有枚举值"Mr Mrs Ms"。
对于属性而言,属性通常是附属于元素的,因此将属性声明为全局的意义不大,除非多个元素要使用相同的属性。
[+/-] |
XML schema 中 elementFormDefault |
XML schema 中 elementFormDefault
一个 XML schema 中 elementFormDefault="?" 这一属性用来指示 XML Schema 处理程序把这个 XML schema 中定义的元素或者类型放到哪个命名空间。一个schema中声明的元素或者类型只能归到两个命名空间中的某一个去,这两个是,无名命名空间和由targetSchema属性指明的目标命名空间。 而targetSchema属性只能在xs:schema的定义中声明,因而,一个schema中的定义的元素或类型只可能归属于一个有名命名空间(但是 还有可能归属于无名命名空间)。
当elementFormDefault="qualified" 时,所有全局元素的子元素将被以缺省方式放到目标命名空间,但是全局元素或者类型将被 放到目标命名空间;而当elementFormDefault="unqualified" 时,所有全局元素的子元素将被以缺省方式放到无名命名空间。 而属性的命名空间类似地由attributeFormDefault="?"来指明。
需要明白的是,elementFormDefault="?" 是有作用域的,并且是被继承的,除非在子定义中覆盖父定义。
下面三个例子说明了elementFormDefault的使用效果。红色表示属于已命名空间的元素,蓝色表示属于未命名空间的元素。
1.定义了目标命名空间, 全局elementFormDefault=“unqualified”。这时除了全局元素或者类型将归于目标命名空间外,局部元素将归于无名命名空间。
unqualified.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="aaaa" elementFormDefault="unqualified" attributeFormDefault="unqualified">
<xs:element name="c">
<xs:complexType>
<xs:sequence>
<xs:element name="c1" type="xs:double"/>
<xs:element name="c2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
unqualified.xml
<?xml version="1.0" encoding="UTF-8"?>
<n:c xmlns:n="aaaa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="aaaa unqualified.xsd">
<c1>3.141593E0</c1>
<c2>String</c2>
</n:c>
2. 定义了目标命名空间, 全局elementFormDefault=“qualified”。这时全局元素或者类型将归于目标命名空间,局部元素将以缺省方式归于目标命名空间。
qualified.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="aaaa" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="c">
<xs:complexType>
<xs:sequence>
<xs:element name="c1" type="xs:double"/>
<xs:element name="c2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
qualified.xml
<?xml version="1.0" encoding="UTF-8"?>
<c xmlns="aaaa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="aaaa qualified.xsd">
<c1>3.141593E0</c1>
<c2>String</c2>
</c>
3. 定义了目标命名空间, 全局elementFormDefault=“unqualified”。这时全局元素(c)或者类型将归于目标命名空间。 局部元素(c1,c2)以缺省方式归于无名命名空间。局部元素(c3)在局部定义中使用form=“qualified”覆盖全局设定的 unqualified,这使得c3归于目标命名空间(如果它有子元素,子元素将以缺省方式归于目标命名空间)。
qualified2.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="aaaa" elementFormDefault="unqualified" attributeFormDefault="unqualified">
<xs:element name="c">
<xs:complexType>
<xs:sequence>
<xs:element name="c1" type="xs:double"/>
<xs:element name="c2" type="xs:string"/>
<xs:element name="c3" type="xs:integer" form="qualified"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
qualified2.xml
<?xml version="1.0" encoding="UTF-8"?>
<n:c xmlns:n="aaaa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="aaaa qualified2.xsd">
<c1>3.141593E0</c1>
<c2>String</c2>
<n:c3>0</n:c3>
</n:c>
2009年12月16日星期三
[+/-] |
XML中namespace 命名空间的作用 |
相信很多程序员刚接触XML的时候,对XML中的Namespace的用法不是很清楚,而且甚至不知道它到底有什么用,包括最初我自己也是。
不过之所以不理解这种Namespace主要是因为我们都习惯于将具有相同或者相近内容放在一个XML中,所以不会遇到一些问题。
看下面的情形:
<html xmlns="http://www.w3.org/HTML/1998/html4"
xmlns:xdc="http://www.xml.com/books">
<head><title>Book Review</title></head>
<:body>
<xdc:bookreview>
<xdc:title>XML: A Primer</xdc:title>
<table>
<tr align="center">
<td>Author</td><td>Price</td>
<td>Pages</td><td>Date</td></tr>
<tr align="left">
<td><xdc:author>Simon St. Laurent</xdc:author></td>
<td><xdc:price>31.98</xdc:price></td>
<td><xdc:pages>352</xdc:pages></td>
<td><xdc:date>1998/01</xdc:date></td>
</tr>
</table>
</xdc:bookreview>
</body>
</html>
这里边有两个title元素,如果不属于不同的命名空间就很难分清楚,解决的办法就是添加一个Namespace :xmlns:xdc=http://www.xml.com/books
这样就不至于将html中的title元素和这里的title搞混淆了,而且在读取的时候,比如XmlReader之类的只要指定对应的命名空间 就会读取该命名空间下的节点,这样就不会发生错误了。
同时xmlns=http://www.w3.org/HTML/1998/html4这里就是设置默认的命名空间为http://www.w3.org/HTML/1998/html4
可能大家还会造成一定的误解,xmlns通常会制定为url,但是实际上这些url不一定是要存在的,也不一定是url,只要能够不至于让这个命名 空间在其它xml文档出现就可以了,而一般之所以用url这是为了避免重复出现的可能性,因为一般不同的国家不同的程序员不会把Namespace指定为 相同的,且url各不相同;但如果仅仅是简单的一些字符串则有可能出现不同xml文档 当命名空间相同的情况,而原本并不属于同一命名空间。也就是说Namespace是没有任何特定含义的,只是用于唯一标识这个命名空间。
XML中的Namespace如果.NET中的类库一样,它们仅用来唯一标识一组元素,就好想不同的dll中有可能有相同类名的情况,但却不属于不同的命名空间。
不过,我个人觉得XML的命名空间有点像鸡肋,因为它很容易给人造成误解,特别是用url来标识命名空间的时候,在平时运用中也不是很多,网上也有很多讨论XML的Namespace是否应该存在的话题。
参考这篇文档讲述得比较的清楚 http://www.xml.com/pub/a/1999/01/namespaces.html