XML 스키마 편집은 SOM(스키마 개체 모델)의 가장 중요한 기능 중 하나입니다. SOM의 모든 사전 스키마 컴파일 속성을 사용하여 XML 스키마의 기존 값을 변경할 수 있습니다. 그런 다음 변경 내용을 반영하도록 XML 스키마를 다시 컴파일할 수 있습니다.
SOM에 로드된 스키마를 편집하는 첫 번째 단계는 스키마를 트래버스하는 것입니다. 스키마를 편집하기 전에 SOM API를 사용하여 스키마를 트래버스하는 방법을 잘 알고 있어야 합니다. PSCI(Post-Schema-Compilation-Infoset)의 스키마 전 및 사후 컴파일 속성도 잘 알고 있어야 합니다.
XML 스키마 편집
이 섹션에서는 XML 스키마 빌드 항목에서 만든 고객 스키마를 편집하는 두 가지 코드 예제가 제공됩니다. 첫 번째 코드 예제에서는 요소에 PhoneNumber
새 Customer
요소를 추가하고 두 번째 코드 예제는 요소에 Title
새 FirstName
특성을 추가합니다. 첫 번째 샘플에서는 스키마 컴파일 후 컬렉션을 고객 스키마 XmlSchema.Elements 를 트래버스하는 수단으로 사용하고 두 번째 코드 예제에서는 스키마 XmlSchema.Items 컴파일 전 컬렉션을 사용합니다.
PhoneNumber 요소 예제
이 첫 번째 코드 예제는 고객 스키마의 PhoneNumber
요소에 새 Customer
요소를 추가합니다. 코드 예제에서는 다음 단계에서 고객 스키마를 편집합니다.
고객 스키마를 새 XmlSchemaSet 개체에 추가한 다음 컴파일합니다. 스키마를 읽거나 컴파일할 때 발생하는 스키마 유효성 검사 경고 및 오류는 대리자가 ValidationEventHandler 처리합니다.
XmlSchema 속성을 반복하여 XmlSchemaSet에서 컴파일된 Schemas 개체를 검색합니다. 스키마가 컴파일되므로 PSCI(Post-Schema-Compilation-Infoset) 속성에 액세스할 수 있습니다.
PhoneNumber
요소를 XmlSchemaElement 클래스를 사용하여 생성하고,xs:string
및 XmlSchemaSimpleType 클래스를 사용하여 XmlSchemaSimpleTypeRestriction 단순 형식 제한을 생성하고, 제한의 Facets 속성에 패턴 패싯을 추가하고, 제한을 단순 형식의 Content 속성에 추가하고, 단순 형식을 SchemaType 요소의PhoneNumber
속성에 추가합니다.사후 스키마 컴파일 XmlSchemaElement 컬렉션의 Values 내의 각 XmlSchema.Elements를 반복 처리합니다.
QualifiedName가 요소
"Customer"
인 경우,Customer
클래스를 사용하여 XmlSchemaComplexType 요소의 복합 유형을 가져오고, XmlSchemaSequence 클래스를 사용하여 복합 유형의 시퀀스 파티클을 가져옵니다.시퀀스의 사전 스키마 컴파일
PhoneNumber
컬렉션을 사용하여 기존FirstName
요소와LastName
요소가 포함된 시퀀스에 새 Items 요소를 추가합니다.마지막으로, XmlSchema 클래스의 Reprocess 및 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 속성 예제
이 두 번째 코드 예제에서는 고객 스키마의 Title
요소에 새 FirstName
특성을 추가합니다. 첫 번째 코드 예제에서 요소의 FirstName
형식은 .입니다 xs:string
.
FirstName
요소가 문자열 콘텐츠와 함께 특성을 가지려면 해당 형식을 간단한 콘텐츠 확장 콘텐츠 모델이 있는 복합 형식으로 변경해야 합니다.
코드 예제에서는 다음 단계에서 고객 스키마를 편집합니다.
고객 스키마를 새 XmlSchemaSet 개체에 추가한 다음 컴파일합니다. 스키마를 읽거나 컴파일할 때 발생하는 스키마 유효성 검사 경고 및 오류는 대리자가 ValidationEventHandler 처리합니다.
XmlSchema 속성을 반복하여 XmlSchemaSet에서 컴파일된 Schemas 개체를 검색합니다. 스키마가 컴파일되므로 PSCI(Post-Schema-Compilation-Infoset) 속성에 액세스할 수 있습니다.
클래스를 사용하여
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 컬렉션을 사용하여 스키마를 트래버스합니다. 두 컬렉션 모두 스키마의 전역 요소에 대한 액세스를 제공하지만 스키마의 모든 전역 요소를 반복해야 하며 PSCI 속성이 없으므로 컬렉션을 반복 Items 하는 데 시간이 더 많이 걸립니다. PSCI 컬렉션(XmlSchema.Elements, XmlSchema.Attributes등 XmlSchema.SchemaTypes)은 전역 요소, 특성 및 형식 및 해당 PSCI 속성에 대한 직접 액세스를 제공합니다.
XmlSchemaObject 요소가 QualifiedName가
"Customer"
인 경우,Customer
클래스를 사용하여 XmlSchemaComplexType 요소의 복합 유형을 얻고, XmlSchemaSequence 클래스를 사용하여 해당 복합 유형의 시퀀스 파티클을 얻습니다.스키마 컴파일 이전 단계 XmlSchemaParticle 컬렉션의 각 XmlSchemaSequence.Items를 반복합니다.
XmlSchemaParticle 요소가 QualifiedName으로
"FirstName"
인 경우, SchemaTypeName 요소의FirstName
을(를) 새로운FirstName
복합 형식으로 설정합니다.마지막으로, XmlSchema 클래스의 Reprocess 및 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>
참고하십시오
.NET