포함된 스키마를 병합하기 위해 스키마 전처리
적용 대상: SQL Server Azure SQL 데이터베이스 Azure SQL Managed Instance
W3C XSD include 요소는 XML 스키마를 두 개 이상의 실제 파일로 분할할 수 있는 스키마 모듈화를 지원합니다. 현재 SQL Server에서는 이 요소를 지원하지 않습니다. 이 요소를 포함하는 XML 스키마는 서버에서 거부됩니다.
이러한 문제를 해결하기 위해 <xsd:include>
지시문을 포함하고 있는 XML 스키마는 전처리하여 포함된 모든 스키마의 내용을 하나의 스키마로 복사 및 병합해서 서버에 업로드할 수 있습니다. 다음 C# 코드는 전처리에 사용될 수 있습니다. 코드의 초기 부분에 있는 설명은 코드를 사용하는 방법에 대한 정보를 제공합니다.
// XSD Schema Include Normalizer
// To compile:
// csc filename.cs
//
// How to use:
//
// Arguments: [-q] input.xsd [output.xsd]
//
// input.xsd - file to normalize
// output.xsd - file to output, default is console
// -q - quiet
//
// Example:
//
// filename.exe schema.xsd
//
using System;
using System.Xml;
using System.Xml.Schema;
using System.IO;
using System.Collections;
public class XsdSchemaNormalizer
{
private static bool NormalizeXmlSchema( String url, TextWriter writer )
{
try {
XmlTextReader txtRead = new XmlTextReader( url );
XmlSchema sch = XmlSchema.Read( txtRead, null );
// Compiling Schema
sch.Compile(null);
XmlSchema outSch =
XmlSchemaIncludeNormalizer.BuildIncludeFreeXmlSchema( sch);
outSch.Write( writer );
} catch ( Exception e ) {
Console.WriteLine(e.ToString());
return false;
}
return true;
}
public static void usage()
{
Console.WriteLine("Arguments: [-q] [-v] input.xsd [output.xsd]\n");
Console.WriteLine("input.xsd - file to normalize");
Console.WriteLine("output.xsd - file to output, default is console");
Console.WriteLine("-q - quiet");
}
public static void Main(String []args)
{
if( args.GetLength(0) < 1 ) {
usage();
return;
}
int argi = 0;
bool quiet = false;
if( args[argi] == "-q" ) {
quiet = true;
argi++;
}
if( argi == args.GetLength(0) )
{
usage();
return;
}
String url = args[argi];
if( !quiet )
Console.WriteLine("Loading Schema: " + url);
if( argi < ( args.GetLength(0) - 1 ) )
{
if( !quiet )
Console.WriteLine("Outputing to file: " + args[argi+1]);
StreamWriter output =
new StreamWriter( new FileStream(args[argi+1], FileMode.Create ));
NormalizeXmlSchema( url, output);
}
else
{
NormalizeXmlSchema( url, Console.Out);
}
}
}
// A class to remove all <include> from a Xml Schema
//
public class XmlSchemaIncludeNormalizer
{
// Takes as input a XmlSchema which has includes in it
// and the schema location uri of that XmlSchema
//
// Returns a "preprocessed" form of XmlSchema without any
// includes. It still retains imports though. Also, it does
// not propagate unhandled attributes
//
// It can throw any exception
public static XmlSchema BuildIncludeFreeXmlSchema( XmlSchema inSch )
{
XmlSchema outSch = new XmlSchema();
AddSchema( outSch, inSch );
return outSch;
}
// Adds everything in the second schema minus includes to
// the first schema
//
private static void AddSchema( XmlSchema outSch, XmlSchema add)
{
outSch.AttributeFormDefault = add.AttributeFormDefault;
outSch.BlockDefault = add.BlockDefault;
outSch.ElementFormDefault = add.ElementFormDefault;
outSch.FinalDefault = add.FinalDefault;
outSch.Id = add.Id;
outSch.TargetNamespace = add.TargetNamespace;
outSch.Version = add.Version;
AddTableToSchema( outSch, add.AttributeGroups );
AddTableToSchema( outSch, add.Attributes );
AddTableToSchema( outSch, add.Elements );
AddTableToSchema( outSch, add.Groups );
AddTableToSchema( outSch, add.Notations );
AddTableToSchema( outSch, add.SchemaTypes );
// Handle includes as a special case
for( int i = 0; i < add.Includes.Count; i++ )
{
if( ! ( add.Includes[i] is XmlSchemaInclude) )
outSch.Includes.Add( add.Includes[i] );
}
}
// Adds all items in the XmlSchemaObjectTable to the specified XmlSchema
//
private static void AddTableToSchema( XmlSchema outSch,
XmlSchemaObjectTable table )
{
IDictionaryEnumerator e = table.GetEnumerator();
while( e.MoveNext() )
{
outSch.Items.Add( (XmlSchemaObject)e.Value );
}
}
}
전처리기 도구 테스트
다음 XSD 스키마를 사용하여 전처리기 도구를 테스트할 수 있습니다.
books_common.xsd
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="bookstore-schema"
elementFormDefault="qualified" >
<xsd:element name="publisher" type="xsd:string"/>
</xsd:schema>
books.xsd
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="bookstore-schema"
elementFormDefault="qualified"
targetNamespace="bookstore-schema">
<xsd:include id="books_common" schemaLocation="books_common.xsd"/>
<xsd:element name="bookstore" type="xsd:string" />
</xsd:schema>