XmlXsdDocument






4.56/5 (4投票s)
2006 年 10 月 27 日
10分钟阅读

24914

570
本文解释了 XmlXsdDocument 类的应用。
引言
本文介绍了一个类,该类用于包含来自 XmlDocument
的节点信息,以及来自相应 XmlSchema
的信息。
这些类是待实现的类
实现
我们如何同时读取 XML 和 XSD 文档,并构建一个包含来自两个文档的组合信息的节点文档。
当我们需要从 XmlDocument
文件中读取信息时,我们使用 System.Xml.XmlDocument
类。此类不仅可以读取孤立的 XML 文件,还可以同时读取相应的 XSD 架构文件,并在该过程中应用必要的验证。
当我们想要拦截此过程时,我们需要实现一个派生自 System.Xml.XmlValidatingReader
的类,并重写 Read
方法。每次基类开始或停止从 XML 文件读取节点时,都会调用此方法。此时,基类已包含有关当前读取节点的信息,例如:名称、值以及从 XSD 文件中提取的信息。遗憾的是,它不包含我们目标所需的关键信息;它没有返回由当前读取节点描述的 System.Xml.Schema.XmlSchemaElement
的属性。
我们如何克服这个障碍?请参阅以下项目文件:Puma.Xml.XmlValidatingReader.cs, Puma.Xml.XmlXsdNodeBuilder.cs。
为了测试,只需将项目属性更改为\输出类型\控制台应用程序。
完整项目静态架构
使用代码
Puma.Xml.XmlXsdDocument 类
此类创建 XML 的树表示。此树不仅包含 XML 的信息,还包含来自相应 XSD 架构的关联信息。XML 和关联的 XSD 文档的树表示使得 XML 文档的导航和编辑成为可能。此外,此类还提供了一个方法,用于从相应的 XSD 创建 XML 文件。
限制:
此类只能处理内容受限的文档:例如,complexType
的元素只能有一个 sequence
子项。
构造函数:
public XmlXsdDocument(string XmlFileName, string XsdFileName)
从指定文件加载 XML 和 XSD 文档
public XmlXsdDocument(string XsdFileName)
创建符合 XSD 文件的 XML 文件。
public XmlXsdDocument(string XmlFileName, string XsdFileName, NodeExtensible NodeExtensible)
从指定文件加载 XML 和 XSD 文档。加载时,将调用 NodeExtensible
类的重写方法。
public XmlXsdDocument(string XsdFileName, NodeExtensible NodeExtensible)
创建符合 XSD 文件的 XML 文件。创建时,将调用 NodeExtensible
类的重写方法。
public XmlXsdDocument(string XsdFileName, ConstructParams ConstructParams, NodeExtensible NodeExtensible)
根据 XSD 文件和 ConstructParams
参数创建 XML 文件。创建时,将调用 NodeExtensible
类的重写方法。
属性:
public Puma.Xml.XmlDocument XmlDocument
public Puma.Xml.XsdDocument XsdDocument
方法:
public void Save(string FileName)
将 XML 文档保存到指定文件。
public void Save()
将 XML 文档保存到加载它的文件。
public void SaveBin(string FileName)
将 XML 文档保存到指定的二进制文件。
限制:
每个元素的 maxOccurs
属性不能是 unbounded。任何类型为 string
的元素都必须具有 maxLength
限制。文档中任何元素的类型都应被 SaveBin
方法识别。
当前版本支持:String, Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64
。
具有枚举限制的元素应具有非字符串的基类型。
Puma.Xml.ConstructParams 类
Puma.Xml.ConstructParams.ConstructElementParams 类
属性:
public bool UseMinOccurs = true
创建元素时,文档中的数量将等于 minOccurs
属性。否则,它将等于 maxOccurs
(在这种情况下,maxOccurs
不得为 unbounded
)。
Puma.Xml.ConstructParams.ConstructDefaultValueParams 类
属性:
public char StringFillChar = ' '
创建具有 minLength
限制的 string
类型元素时,该值将由一个长度等于 minLength
的字符串初始化,并用 StringFillChar
字符填充。
System.IO.BinaryReader ValueProvider
当从 XSD 架构文件创建 XML 文档,并且此参数不为 null
时,所有创建的 XML 的值都将通过从此读取器读取数据来初始化。
限制:
请参阅 Puma.Xml.XmlXsdDocument.SaveBeen()
限制。
Puma.Xml.NodeExtensible 类
此类有助于扩展文档节点或文档本身的函数。当 XmlXsdDocument
在节点树中创建节点时,我们可以调用此类的一个方法,并使用返回的 TagEx
属性对象来初始化节点。之后,我们可以通过相应节点的 TagEx
属性轻松访问返回的对象。
方法:
virtual object OnXmlNodeCreated(Puma.Xml.XmlNode XmlNode)
当文档完成 XmlNode
的创建时调用。
virtual object OnXsdNodeCreated(Puma.Xml.XsdNode XsdNode)
当文档完成 XsdNode
的创建时调用。
virtual object OnXmlXsdNodeCreated(Puma.Xml.XmlXsdNode XmlXsdNode)
当文档完成 XmlXsdNode
的创建时调用。
virtual object OnXmlDocumentCreated(Puma.Xml.XmlDocument XmlDocument)
当文档完成 XmlDocument
的创建时调用。
virtual object OnXsdDocumentCreated(Puma.Xml.XsdDocument XsdDocument)
当文档完成 XsdDocument
的创建时调用。
virtual object OnXmlXsdDocumentCreated(Puma.Xml.XmlXsdDocument XmlXsdDocument)
当文档完成自身的创建时调用。
Puma.Xml.XmlXsdNode 类
此类包含文档节点的有关信息。由于文档树的组成部分具有访问子节点和父节点的属性,因此组合信息从 XML 和 XSD 文档中提取。
属性:
Puma.Xml.XmlXsdDocument XmlXsdDocument
包含此节点的文档。
public Puma.Xml.XmlNode XmlNode
描述 XML 文档中的节点。
public Puma.Xml.XsdNode XsdNode
描述 XSD 文档中的节点。
object Parent
检索父节点(类型为 Puma.Xml.XmlXsdDocument
或 Puma.Xml.XmlXsdNode
)。
public string Name
检索节点名称。
public bool IsComplexType
定义节点是否可以具有子节点。
public string Value
检索节点值。
public object TypedValue
检索节点类型化值。
public XmlXsdNodeCollection Childs
检索子节点集合。
Puma.Xml.XmlXsdNodeCollection 类
表示节点的子节点集合。每个集合细分为多个片段 [请参阅 XmlXsdNodeCollectionFragment
类]。
方法:
public XmlXsdNodeCollectionFragment GetXmlXsdNodeFragment(string FragName)
获取集合的关联片段。
属性:
public XmlXsdNodeCollectionFragment this[string FragName] { get }
获取集合的关联片段。
Puma.Xml.XmlXsdNodeCollectionFragment 类
此类表示具有相同名称的子节点集合。这使得能够从该集合添加或删除节点。
注意:一个节点可能包含一个具有相同名称的子节点集合。当该节点在 XSD 文档中以 maxOccurs
> 1 的属性描述,并在 XML 文档中出现多次时,可能会发生这种情况;所有这些节点都将位于一个 XmlXsdNodeCollectionFragment
容器中。即使 maxOccurs = 1
的情况,单个节点也将位于一个单独的 XmlXsdNodeCollectionFragment
容器中。此外,一个节点可能具有 minOccurs = 0
,并且在 XML 文档中未出现。在这种情况下,也将创建一个 XmlXsdNodeCollectionFragment
。
示例:XSD 文档
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="Node1" type="xs:unsignedByte" maxOccurs="3"/>
<xs:element name="Node2" type="xs:unsignedByte" maxOccurs="1"/>
<xs:element name="Node3" type="xs:unsignedByte" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
XML 文档
<Root>
<Node1>1</Node1>
<Node1>2</Node1>
<Node2>3</Node2>
</Root>
foreach(XmlXsdNodeCollectionFragment frag in rootXmlXsdNode)
{
System.Console.WriteLine("Frag name: ” + frag.Name);
Foreach(XmlXsdNode child in frag)
{
System.Console.WriteLine("Child name: ” + child.Name +
", val= " + child.Value);
}
}
控制台
Frag name: Node1
Child name: Node1, Val = 1
Child name: Node1, Val = 2
Frag name: Node2
Child name: Node2, Val = 3
Frag name: Node3
属性:
public XsdNode TemplateXsdNode
返回包含与当前片段的节点相关的 XSD 文档信息的节点。
public XmlXsdNode this[int Index]
检索给定索引处的节点。
public XmlXsdNode LastNode
检索最后一个节点。如果不存在节点,则返回 null
。
public bool IsCanInsert
定义是否可以将节点添加到片段。
public bool IsCanRemove
定义是否可以从片段中删除节点。
方法:
public XmlXsdNode InsertXmlXsdNode(int Index)
此方法根据 TemplateXsdNode
成员中包含的信息创建一个节点,并将其插入到文档中。节点插入到具有相同索引的片段节点的后面。如果 Index = -1
,则节点放置在片段的末尾。
值初始化方式如下
- 如果此节点存在默认值,则应用该默认值。
- 如果值是字符串类型且具有
minLength
限制,则用长度等于minLength
的字符串初始化,并用ConstructDefaultValueParams.StringFillChar
字符填充(请参阅Puma.Xml.ConstructParams
类)。 - 如果值具有枚举限制,则用遇到的第一个枚举值初始化。
- 如果该值是数据类型值并实现了一个
MinValue
静态属性,则由该属性初始化。 - 如果以上任何一种情况都不满足,则值初始化为
null
。
注释:
当创建复杂节点时使用,其中子节点元素的数量取决于 ConstructElementParams.UseMinOccurs
参数(请参阅 Puma.Xml.ConstructParams
类)。如果此值为 true
,则数量等于 minOccurs
;否则,它等于 maxOccurs
。
异常:
Puma.Xml.XmlExceptions.ChildCollectionXmlException[ChildCollectionExceptionCode = Puma.Xml.XmlExceptions.ChildCollectionExceptionCode.NodeIndexInvalid]
当片段的索引超出范围时发生(索引超过片段中的元素数量)。
Puma.Xml.XmlExceptions.ChildCollectionXmlException[ChildCollectionExceptionCode = Puma.Xml.XmlExceptions.ChildCollectionExceptionCode. MaxOccursLimitExcited]
当无法向片段添加节点时发生(节点数量超过 maxOccurs
)。
示例:XSD 文档
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="Node1" minOccurs=”0”>
<xs:complexType>
<xs:sequence>
<xs:element name="Node11"
type="xs:unsignedByte" default=”100” />
<xs:element name="Node12"
type="xs:unsignedByte" minOccurs=”3”/>
<xs:element name="Node13" >
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Enum1" pge:ParentValuePart="true">
<xs:simpleType>
<xs:restriction base="xs:unsignedByte">
<xs:enumeration value="2"/>
<xs:enumeration value="3"/>
<xs:enumeration value="8"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
XML 文档
<Root>
</Root>
/////////////////////////////////
//Load XML and XSD in Puma.Xml.XmlXsdDocument, get <ROOT> node
Puma.Xml.XmlXsd.XmlXsdNodeCollectionFragment frag =
rootXmlXsdNode["Node1"];
//Use ConstructElementParams.UseMinOccurs = true and
//ConstructDefaultValueParams.StringFillChar = 'x'
Puma.Xml.XmlXsd.XmlXsdNode insertedNode =
frag.InsertXmlXsdNode(-1);
Foreach(XmlXsdNodeCollectionFragment insFrag in insertedNode)
{
System.Console.WriteLine("Frag name: ” + insFrag.Name);
Foreach(XmlXsdNode child in insFrag)
{
System.Console.WriteLine("Child name: ” +
child.Name ", val= " + child.Value);
}
}
控制台
Frag name: Node11
Child name: Node1, Val = 100
Frag name: Node12
Child name: Node12, Val = 0
Child name: Node12, Val = 0
Child name: Node12, Val = 0
Frag name: Node13
Child name: Node13, Val = xxxxx
Frag name: Enum1
Child name: Enum1, Val = 2
public XmlXsdNode RemoveXmlXsdNode(int Index)
从片段和文档中删除索引为 Index
的节点。
异常:
Puma.Xml.XmlExceptions.ChildCollectionXmlException[ChildCollectionExceptionCode = Puma.Xml.XmlExceptions.ChildCollectionExceptionCode.NodeIndexInvalid]
当片段的索引超出范围时发生(Index
超过片段中的元素数量)。
Puma.Xml.XmlNode 类
此类便于处理 System.Xml.XmlElement
类。
成员:
public readonly Puma.Xml.XmlXsdNode container
获取此类容器。
属性:
public System.Xml.XmlElement XmlElement
获取包含的 System.Xml.XmlElement
元素。
Puma.Xml.XsdNode 类
此类便于处理 System.Xml.Schema.XmlSchemaElement
类。
成员:
public readonly Puma.Xml.XsdSimpleType XsdSimpleType
请参阅 Puma.Xml.XsdSimpleType
类
public readonly XmlXsdNode container
获取此类容器。
属性:
public System.Xml.Schema.XmlSchemaElement XmlSchemaElement
获取包含的 System.Xml.XmlSchemaElement
元素。
public bool IsComplexType
返回 true
表示元素具有复杂类型(包含子节点)。
public Puma.Xml.MinMaxOccurs MinMaxOccurs
返回 minOccurs
和 maxOccurs
节点属性。
public string Annotation
返回节点注释 [请参阅 xs:annotation
]。
public bool IsReadOnly
返回表示节点是只读的 [请参阅 msadata:ReadOnly
属性]。
public string Caption
返回节点标题 [请参阅 msdata:Caption
属性]。
Puma.Xml.XsdSimpleType 类
此类便于处理从 XSD 文档中提取的信息,这些信息描述了节点的类型。
成员:
public readonly XsdNode Container
获取此类容器。
public readonly XmlSimpleTypeRestriction Restriction
获取节点的限制。
属性:
public System.Xml.Schema.XmlSchemaSimpleType SimpleType
获取节点的简单类型。
public System.Xml.Schema.XmlSchemaDatatype DataType
获取节点的日期类型。
public System.Type ValueType
获取与 XSD 文档节点类型关联的系统类型。请参阅 MSDN:将 XML 数据类型映射到 CLR 类型。
XmlSimpleTypeRestriction 类
此类便于处理由节点类型的限制描述的信息。
枚举:
public enum XsdSimpleTypeRestriction
{
MinLength = 0x1,
MaxLength = 0x10,
MinValue = 0x100,
MaxValue = 0x1000,
Enumeration = 0x10000,
All = 0x11111
}
此枚举定义了限制类型。
属性:
public System.Xml.Schema.XmlSchemaSimpleTypeRestriction Restriction
获取节点的 System.Xml.Schema.XmlSchemaSimpleTypeRestriction
。
public System.Xml.Schema.XmlSchemaObjectCollection Facets
获取节点的 System.Xml.Schema.XmlSchemaSimpleTypeRestriction
。
public bool IsEnum
返回指示节点类型是否具有 enumeration
限制。
public bool IsMinValue
返回指示节点类型是否具有 minValue
限制。
public bool IsMaxValue
返回指示节点类型是否具有 maxValue
限制。
public bool IsMinLength
返回指示节点类型是否具有 minLength
限制。
public bool IsMaxLength
返回指示节点类型是否具有 maxLength
限制。
public int MinLengthRestriction
返回节点的 minLength
限制。如果未找到限制,则返回 -1。
public int MaxLengthRestriction
返回节点的 maxLength
限制。如果未找到限制,则返回 -1。
public EnumerationRestriction EnumerationRestriction
返回节点的枚举限制。
方法:
public object GetRestriction(XsdSimpleTypeRestriction TypeRestriction)
按类型获取限制。如果未找到具有此类型的限制,则返回 null
。返回对象的类型可以是以下之一:Puma.Xml.EnumerationRestriction
、Puma.Xml.MinMaxLengthRestriction
、Puma.Xml.MinMaxValueRestriction
。
public object GetFirstRestrictionValue(XsdSimpleTypeRestriction TypeRestriction)
按类型获取节点限制的值。如果存在多个具有相同类型的限制(例如枚举),则返回第一个。
public object[] GetRestrictions()
获取所有类型节点限制。如果未找到,则返回 null
。有关返回对象类型的信息,请参阅 GetRestriction
方法。
public object[] GetRestrictions(int TypeRestrictions)
按类型获取类型节点限制的数组。如果未找到,则返回 null
。有关返回对象类型的信息,请参阅 GetRestriction
方法。
致谢
感谢 **Arnie Berg** 为本文的撰写做出的贡献。