2010-07-29 3 views
2

Мне нужно расширить существующий документ XML новыми элементами, не теряя возможности проверить его как с неизменной исходной схемой, так и с расширенной схемой, определенной мной.Расширение сложных типов из существующей схемы

Например, позволяет сказать, что я хочу добавить Code и Price элементы к существующему Book документе следующим образом:

<aa:Book xmlns:aa="http://www.aa.com" 
     xmlns:bb="http://www.bb.com"> 
    <aa:Title>Complete Works</aa:Title> 
    <aa:Author>Shakespeare</aa:Author> 
    <bb:Code>98</bb:Code> 
    <bb:Price>31.6</bb:Price> 
</aa:Book> 

Исходная схема (который я не могу изменить) будет выглядеть примерно так:

<xs:schema targetNamespace="http://www.aa.com" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns="http://www.aa.com" 
      elementFormDefault="qualified"> 
    <xs:element name="Book" type="Book--type" /> 
    <xs:complexType name="Book--type"> 
    <xs:sequence> 
     <xs:element name="Title" type="xs:string" /> 
     <xs:element name="Author" type="xs:string" /> 
    </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

Как создать новую схему, которая определяет эти новые элементы таким образом, чтобы SchemaSet, содержащий обе эти схемы, мог успешно проверить расширенный документ XML выше?

Я пробовал следующий обычный сложный шаблон расширения типа:

<xs:schema targetNamespace="http://www.bb.com" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns="http://www.bb.com" 
      xmlns:aa="http://www.aa.com" 
      elementFormDefault="qualified"> 
    <xs:import namespace="http://www.aa.com" /> 
    <xs:complexType name="Book--type"> 
    <xs:complexContent> 
     <xs:extension base="aa:Book--type"> 
     <xs:sequence> 
      <xs:element name="Code" type="xs:int" /> 
      <xs:element name="Price" type="xs:double" /> 
     </xs:sequence> 
     </xs:extension> 
    </xs:complexContent> 
    </xs:complexType> 
</xs:schema> 

Однако это приводит к ошибкам о том, что элемент aa:Book не определяет дочерний элемент bb:Code, что делает общий смысл.

Возможно ли это?

Для справки, вот код, я использую для проверки документа:

var fail = new ValidationEventHandler((sender, e) => Debug.Fail(e.Message)); 
var schemaSet = new XmlSchemaSet(); 
schemaSet.Add(XmlSchema.Read(new StringReader(original), fail)); 
schemaSet.Add(XmlSchema.Read(new StringReader(extension), fail)); 
var settings = new XmlReaderSettings 
    { 
     ValidationType = ValidationType.Schema, 
     Schemas = schemaSet 
    }; 
settings.ValidationEventHandler += fail; 
using (var stream = File.OpenRead(fileName)) 
using (var reader = XmlReader.Create(stream, settings)) 
{ 
    while (reader.Read()) {} 
} 

ответ

1

оказывается, что xs:redefine - это то, что я искал. Он позволяет переопределить существующий элемент в новой схеме, не касаясь исходной схемы или проверяемого документа.

Используя свой оригинальный пример, книга может быть расширена с помощью следующих двух схем:

<xs:schema targetNamespace="http://www.bb.com" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns="http://www.bb.com" 
      elementFormDefault="qualified"> 
    <xs:element name="Code" type="xs:int" /> 
    <xs:element name="Price" type="xs:double" /> 
</xs:schema> 

<xs:schema targetNamespace="http://www.aa.com" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns="http://www.aa.com" 
      xmlns:bb="http://www.bb.com" 
      elementFormDefault="qualified"> 
    <xs:import namespace="http://www.bb.com" /> 
    <xs:redefine schemaLocation="http://www.aa.com"> 
    <xs:complexType name="Book--type"> 
     <xs:complexContent> 
     <xs:extension base="Book--type"> 
      <xs:sequence> 
      <xs:element ref="bb:Code" /> 
      <xs:element ref="bb:Price" /> 
      </xs:sequence> 
     </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 
    </xs:redefine> 
</xs:schema> 
0

Проблема заключается в том, что даже если у вас есть новый тип, определенный в вашей схеме В, корневой элемент в вашей выборке документ типа Book--type от первоначальной схемы А.

Вы должны использовать тип переопределения в документе, например, так:

<aa:Book xmlns:aa="http://www.aa.com" 
     xmlns:bb="http://www.bb.com" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:type="bb:Book--type"> 
    <aa:Title>Complete Works</aa:Title> 
    <aa:Author>Shakespeare</aa:Author> 
    <bb:Code>98</bb:Code> 
    <bb:Price>31.6</bb:Price> 
</aa:Book> 
+0

К сожалению, я не позволил изменить документ проверяемого либо! К счастью, я обнаружил xs: redefine, который похож на то, что мне нужно. –

Смежные вопросы