编辑 XML 架构是架构对象模型(SOM)最重要的功能之一。 SOM 的所有预架构编译属性都可用于更改 XML 架构中的现有值。 然后,可以重新编译 XML 架构以反映更改。
编辑加载到 SOM 中的架构的第一步是遍历架构。 在尝试编辑架构之前,应熟悉使用 SOM API 遍历架构。 还应熟悉后架构Compilation-Infoset(PSCI)的架构前编译属性和后架构编译属性。
编辑 XML 架构
在本部分中,提供了两个代码示例,这两个示例都编辑在 生成 XML 架构 主题中创建的客户架构。 第一个 PhoneNumber
代码示例向元素添加新元素 Customer
,第二个 Title
代码示例向 FirstName
元素添加新属性。 第一个示例还使用架构后编译 XmlSchema.Elements 集合作为遍历客户架构的方法,而第二个代码示例则使用预架构编译 XmlSchema.Items 集合。
PhoneNumber 元素示例
第一个代码示例将新 PhoneNumber
元素添加到 Customer
客户架构的元素。 代码示例在以下步骤中编辑客户架构。
将客户架构添加到新 XmlSchemaSet 对象,然后对其进行编译。 任何架构验证警告和错误在读取或编译架构时由委托ValidationEventHandler处理。
通过循环访问XmlSchema属性从XmlSchemaSet中检索已Schemas编译的对象。 由于架构已编译,因此可以访问架构后Compilation-Infoset (PSCI) 属性。
使用
PhoneNumber
类创建 XmlSchemaElement 元素,使用xs:string
和 XmlSchemaSimpleType 类对 XmlSchemaSimpleTypeRestriction 简单类型进行限制,将模式限定添加到限制的 Facets 属性,并将限制添加到简单类型的 Content 属性,再将简单类型添加到 SchemaType 元素的PhoneNumber
。循环访问后架构编译XmlSchemaElement集合中Values集合的每个XmlSchema.Elements项。
如果QualifiedName元素是
"Customer"
,则使用Customer
类获取XmlSchemaComplexType元素的复杂类型,并使用XmlSchemaSequence类获取复杂类型的序列粒子。使用序列的预架构编译
PhoneNumber
集合将新FirstName
元素添加到包含现有LastName
元素和Items元素的序列中。最后,使用XmlSchemaReprocess类和Compile方法重新处理和编译修改XmlSchemaSet的对象,并将其写入控制台。
下面是完整的代码示例。
using System;
using System.Xml;
using System.Xml.Schema;
class XmlSchemaEditExample
{
static void Main(string[] args)
{
// Add the customer schema to a new XmlSchemaSet and compile it.
// Any schema validation warnings and errors encountered reading or
// compiling the schema are handled by the ValidationEventHandler delegate.
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);
schemaSet.Add("http://www.tempuri.org", "customer.xsd");
schemaSet.Compile();
// Retrieve the compiled XmlSchema object from the XmlSchemaSet
// by iterating over the Schemas property.
XmlSchema customerSchema = null;
foreach (XmlSchema schema in schemaSet.Schemas())
{
customerSchema = schema;
}
// Create the PhoneNumber element.
XmlSchemaElement phoneElement = new XmlSchemaElement();
phoneElement.Name = "PhoneNumber";
// Create the xs:string simple type restriction.
XmlSchemaSimpleType phoneType = new XmlSchemaSimpleType();
XmlSchemaSimpleTypeRestriction restriction =
new XmlSchemaSimpleTypeRestriction();
restriction.BaseTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");
// Add a pattern facet to the restriction.
XmlSchemaPatternFacet phonePattern = new XmlSchemaPatternFacet();
phonePattern.Value = "\\d{3}-\\d{3}-\\d(4)";
restriction.Facets.Add(phonePattern);
// Add the restriction to the Content property of the simple type
// and the simple type to the SchemaType of the PhoneNumber element.
phoneType.Content = restriction;
phoneElement.SchemaType = phoneType;
// Iterate over each XmlSchemaElement in the Values collection
// of the Elements property.
foreach (XmlSchemaElement element in customerSchema.Elements.Values)
{
// If the qualified name of the element is "Customer",
// get the complex type of the Customer element
// and the sequence particle of the complex type.
if (element.QualifiedName.Name.Equals("Customer"))
{
XmlSchemaComplexType customerType =
element.ElementSchemaType as XmlSchemaComplexType;
XmlSchemaSequence sequence =
customerType.Particle as XmlSchemaSequence;
// Add the new PhoneNumber element to the sequence.
sequence.Items.Add(phoneElement);
}
}
// Reprocess and compile the modified XmlSchema object and write it to the console.
schemaSet.Reprocess(customerSchema);
schemaSet.Compile();
customerSchema.Write(Console.Out);
}
static void ValidationCallback(object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Warning)
Console.Write("WARNING: ");
else if (args.Severity == XmlSeverityType.Error)
Console.Write("ERROR: ");
Console.WriteLine(args.Message);
}
}
Imports System.Xml
Imports System.Xml.Schema
Class XmlSchemaEditExample
Shared Sub Main()
' Add the customer schema to a new XmlSchemaSet and compile it.
' Any schema validation warnings and errors encountered reading or
' compiling the schema are handled by the ValidationEventHandler delegate.
Dim schemaSet As XmlSchemaSet = New XmlSchemaSet()
AddHandler schemaSet.ValidationEventHandler, AddressOf ValidationCallback
schemaSet.Add("http://www.tempuri.org", "customer.xsd")
schemaSet.Compile()
' Retrieve the compiled XmlSchema object from the XmlSchemaSet
' by iterating over the Schemas property.
Dim customerSchema As XmlSchema = Nothing
For Each schema As XmlSchema In schemaSet.Schemas()
customerSchema = schema
Next
' Create the PhoneNumber element.
Dim phoneElement As XmlSchemaElement = New XmlSchemaElement()
phoneElement.Name = "PhoneNumber"
' Create the xs:string simple type restriction.
Dim phoneType As XmlSchemaSimpleType = New XmlSchemaSimpleType()
Dim restriction As XmlSchemaSimpleTypeRestriction = _
New XmlSchemaSimpleTypeRestriction()
restriction.BaseTypeName = New XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema")
' Add a pattern facet to the restriction.
Dim phonePattern As XmlSchemaPatternFacet = New XmlSchemaPatternFacet()
phonePattern.Value = "\\d{3}-\\d{3}-\\d(4)"
restriction.Facets.Add(phonePattern)
' Add the restriction to the Content property of the simple type
' and the simple type to the SchemaType of the PhoneNumber element.
phoneType.Content = restriction
phoneElement.SchemaType = phoneType
' Iterate over each XmlSchemaElement in the Values collection
' of the Elements property.
For Each element As XmlSchemaElement In customerSchema.Elements.Values
' If the qualified name of the element is "Customer",
' get the complex type of the Customer element
' and the sequence particle of the complex type.
If element.QualifiedName.Name.Equals("Customer") Then
Dim customerType As XmlSchemaComplexType = _
CType(element.ElementSchemaType, XmlSchemaComplexType)
Dim sequence As XmlSchemaSequence = _
CType(customerType.Particle, XmlSchemaSequence)
' Add the new PhoneNumber element to the sequence.
sequence.Items.Add(phoneElement)
End If
Next
' Reprocess and compile the modified XmlSchema object and write it to the console.
schemaSet.Reprocess(customerSchema)
schemaSet.Compile()
customerSchema.Write(Console.Out)
End Sub
Shared Sub ValidationCallback(ByVal sender As Object, ByVal args As ValidationEventArgs)
If args.Severity = XmlSeverityType.Warning Then
Console.Write("WARNING: ")
Else
If args.Severity = XmlSeverityType.Error Then
Console.Write("ERROR: ")
End If
End If
Console.WriteLine(args.Message)
End Sub
End Class
以下是在 生成 XML 架构 主题中创建的已修改的客户架构。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://www.tempuri.org" targetNamespace="http://www.tempuri.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="FirstName" type="xs:string" />
<xs:element name="LastName" type="tns:LastNameType" />
<xs:element name="PhoneNumber"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="\d{3}-\d{3}-\d(4)" /> </xs:restriction> </xs:simpleType> </xs:element>
</xs:sequence>
<xs:attribute name="CustomerId" type="xs:positiveInteger" use="required" />
</xs:complexType>
</xs:element>
<xs:simpleType name="LastNameType">
<xs:restriction base="xs:string">
<xs:maxLength value="20" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
标题属性示例
第二个代码示例将一个新 Title
属性添加到 FirstName
客户架构的元素。 在第一个代码示例中,元素的类型 FirstName
为 xs:string
.
FirstName
要使元素具有属性以及字符串内容,其类型必须更改为具有简单内容扩展内容模型的复杂类型。
代码示例在以下步骤中编辑客户架构。
将客户架构添加到新 XmlSchemaSet 对象,然后对其进行编译。 任何架构验证警告和错误在读取或编译架构时由委托ValidationEventHandler处理。
通过循环访问XmlSchema属性从XmlSchemaSet中检索已Schemas编译的对象。 由于架构已编译,因此可以访问架构后Compilation-Infoset (PSCI) 属性。
使用
FirstName
类为XmlSchemaComplexType元素创建新的复杂类型。使用基类型
xs:string
以及XmlSchemaSimpleContent和XmlSchemaSimpleContentExtension类创建新的简单内容扩展。使用
Title
类创建新的XmlSchemaAttribute属性,并使用SchemaTypeName的xs:string
将该属性添加到简单内容扩展中。将简单内容的内容模型设置为简单内容扩展,将复杂类型的内容模型设置为简单内容。
将新的复杂类型添加到预架构编译 XmlSchema.Items 集合。
在预架构编译XmlSchemaObject集合中迭代每个XmlSchema.Items。
注释
由于FirstName
元素不是架构中的全局元素,因此在XmlSchema.Items或XmlSchema.Elements集合中不可用。 代码示例首先通过查找FirstName
元素来确定Customer
元素的位置。
第一个代码示例使用在架构编译后得到的XmlSchema.Elements集合来遍历架构。 在此示例中,预架构编译 XmlSchema.Items 集合用于遍历架构。 虽然这两个集合都提供对架构中的全局元素的访问权限,但循环 Items 访问集合更耗时,因为必须循环访问架构中的所有全局元素,并且它没有任何 PSCI 属性。 PSCI 集合(XmlSchema.Elements、XmlSchema.AttributesXmlSchema.SchemaTypes等)提供对其全局元素、属性和类型及其 PSCI 属性的直接访问。
如果XmlSchemaObject是一个元素,其QualifiedName是
"Customer"
,则使用Customer
类获取XmlSchemaComplexType元素的复杂类型,并使用XmlSchemaSequence类获取该复杂类型的序列粒子。在预架构编译XmlSchemaParticle集合中迭代每个XmlSchemaSequence.Items。
如果XmlSchemaParticle是一个元素,且其QualifiedName是
"FirstName"
,则将SchemaTypeName元素的FirstName
设置为新的FirstName
复杂类型。最后,使用XmlSchemaReprocess类和Compile方法重新处理和编译修改XmlSchemaSet的对象,并将其写入控制台。
下面是完整的代码示例。
using System;
using System.Xml;
using System.Xml.Schema;
class XmlSchemaEditExample
{
static void Main(string[] args)
{
// Add the customer schema to a new XmlSchemaSet and compile it.
// Any schema validation warnings and errors encountered reading or
// compiling the schema are handled by the ValidationEventHandler delegate.
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);
schemaSet.Add("http://www.tempuri.org", "customer.xsd");
schemaSet.Compile();
// Retrieve the compiled XmlSchema object from the XmlSchemaSet
// by iterating over the Schemas property.
XmlSchema customerSchema = null;
foreach (XmlSchema schema in schemaSet.Schemas())
{
customerSchema = schema;
}
// Create a complex type for the FirstName element.
XmlSchemaComplexType complexType = new XmlSchemaComplexType();
complexType.Name = "FirstNameComplexType";
// Create a simple content extension with a base type of xs:string.
XmlSchemaSimpleContent simpleContent = new XmlSchemaSimpleContent();
XmlSchemaSimpleContentExtension simpleContentExtension =
new XmlSchemaSimpleContentExtension();
simpleContentExtension.BaseTypeName =
new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");
// Create the new Title attribute with a SchemaTypeName of xs:string
// and add it to the simple content extension.
XmlSchemaAttribute attribute = new XmlSchemaAttribute();
attribute.Name = "Title";
attribute.SchemaTypeName =
new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");
simpleContentExtension.Attributes.Add(attribute);
// Set the content model of the simple content to the simple content extension
// and the content model of the complex type to the simple content.
simpleContent.Content = simpleContentExtension;
complexType.ContentModel = simpleContent;
// Add the new complex type to the pre-schema-compilation Items collection.
customerSchema.Items.Add(complexType);
// Iterate over each XmlSchemaObject in the pre-schema-compilation
// Items collection.
foreach (XmlSchemaObject schemaObject in customerSchema.Items)
{
// If the XmlSchemaObject is an element, whose QualifiedName
// is "Customer", get the complex type of the Customer element
// and the sequence particle of the complex type.
if (schemaObject is XmlSchemaElement)
{
XmlSchemaElement element = schemaObject as XmlSchemaElement;
if (element.QualifiedName.Name.Equals("Customer"))
{
XmlSchemaComplexType customerType =
element.ElementSchemaType as XmlSchemaComplexType;
XmlSchemaSequence sequence =
customerType.Particle as XmlSchemaSequence;
// Iterate over each XmlSchemaParticle in the pre-schema-compilation
// Items property.
foreach (XmlSchemaParticle particle in sequence.Items)
{
// If the XmlSchemaParticle is an element, who's QualifiedName
// is "FirstName", set the SchemaTypeName of the FirstName element
// to the new FirstName complex type.
if (particle is XmlSchemaElement)
{
XmlSchemaElement childElement =
particle as XmlSchemaElement;
if (childElement.Name.Equals("FirstName"))
{
childElement.SchemaTypeName =
new XmlQualifiedName("FirstNameComplexType",
"http://www.tempuri.org");
}
}
}
}
}
}
// Reprocess and compile the modified XmlSchema object and write it to the console.
schemaSet.Reprocess(customerSchema);
schemaSet.Compile();
customerSchema.Write(Console.Out);
}
static void ValidationCallback(object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Warning)
Console.Write("WARNING: ");
else if (args.Severity == XmlSeverityType.Error)
Console.Write("ERROR: ");
Console.WriteLine(args.Message);
}
}
Imports System.Xml
Imports System.Xml.Schema
Class XmlSchemaEditExample
Shared Sub Main()
' Add the customer schema to a new XmlSchemaSet and compile it.
' Any schema validation warnings and errors encountered reading or
' compiling the schema are handled by the ValidationEventHandler delegate.
Dim schemaSet As XmlSchemaSet = New XmlSchemaSet()
AddHandler schemaSet.ValidationEventHandler, AddressOf ValidationCallback
schemaSet.Add("http://www.tempuri.org", "customer.xsd")
schemaSet.Compile()
' Retrieve the compiled XmlSchema object from the XmlSchemaSet
' by iterating over the Schemas property.
Dim customerSchema As XmlSchema = Nothing
For Each schema As XmlSchema In schemaSet.Schemas()
customerSchema = schema
Next
' Create a complex type for the FirstName element.
Dim complexType As XmlSchemaComplexType = New XmlSchemaComplexType()
complexType.Name = "FirstNameComplexType"
' Create a simple content extension with a base type of xs:string.
Dim simpleContent As XmlSchemaSimpleContent = New XmlSchemaSimpleContent()
Dim simpleContentExtension As XmlSchemaSimpleContentExtension = _
New XmlSchemaSimpleContentExtension()
simpleContentExtension.BaseTypeName = _
New XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema")
' Create the new Title attribute with a SchemaTypeName of xs:string
' and add it to the simple content extension.
Dim attribute As XmlSchemaAttribute = New XmlSchemaAttribute()
attribute.Name = "Title"
attribute.SchemaTypeName = _
New XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema")
simpleContentExtension.Attributes.Add(attribute)
' Set the content model of the simple content to the simple content extension
' and the content model of the complex type to the simple content.
simpleContent.Content = simpleContentExtension
complexType.ContentModel = simpleContent
' Add the new complex type to the pre-schema-compilation Items collection.
customerSchema.Items.Add(complexType)
' Iterate over each XmlSchemaObject in the pre-schema-compilation
' Items collection.
For Each schemaObject As XmlSchemaObject In customerSchema.Items
' If the XmlSchemaObject is an element, whose QualifiedName
' is "Customer", get the complex type of the Customer element
' and the sequence particle of the complex type.
If schemaObject.GetType() Is GetType(XmlSchemaElement) Then
Dim element As XmlSchemaElement = CType(schemaObject, XmlSchemaElement)
If (element.QualifiedName.Name.Equals("Customer")) Then
Dim customerType As XmlSchemaComplexType = _
CType(element.ElementSchemaType, XmlSchemaComplexType)
Dim sequence As XmlSchemaSequence = _
CType(customerType.Particle, XmlSchemaSequence)
' Iterate over each XmlSchemaParticle in the pre-schema-compilation
' Items property.
For Each particle As XmlSchemaParticle In sequence.Items
' If the XmlSchemaParticle is an element, who's QualifiedName
' is "FirstName", set the SchemaTypeName of the FirstName element
' to the new FirstName complex type.
If particle.GetType() Is GetType(XmlSchemaElement) Then
Dim childElement As XmlSchemaElement = _
CType(particle, XmlSchemaElement)
If childElement.Name.Equals("FirstName") Then
childElement.SchemaTypeName = _
New XmlQualifiedName("FirstNameComplexType", _
"http://www.tempuri.org")
End If
End If
Next
End If
End If
Next
' Reprocess and compile the modified XmlSchema object and write it to the console.
schemaSet.Reprocess(customerSchema)
schemaSet.Compile()
customerSchema.Write(Console.Out)
End Sub
Shared Sub ValidationCallback(ByVal sender As Object, ByVal args As ValidationEventArgs)
If args.Severity = XmlSeverityType.Warning Then
Console.Write("WARNING: ")
Else
If args.Severity = XmlSeverityType.Error Then
Console.Write("ERROR: ")
End If
End If
Console.WriteLine(args.Message)
End Sub
End Class
以下是在 生成 XML 架构 主题中创建的已修改的客户架构。
<?xml version="1.0" encoding=" utf-8"?>
<xs:schema xmlns:tns="http://www.tempuri.org" targetNamespace="http://www.tempuri.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="FirstName" type="tns:FirstNameComplexType" />
<xs:element name="LastName" type="tns:LastNameType" />
</xs:sequence>
<xs:attribute name="CustomerId" type="xs:positiveInteger" use="required" />
</xs:complexType>
</xs:element>
<xs:simpleType name="LastNameType">
<xs:restriction base="xs:string">
<xs:maxLength value="20" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="FirstNameComplexType"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="Title" type="xs:string" /> </xs:extension> </xs:simpleContent> </xs:complexType>
</xs:schema>