Avatar billede CodingJoe Nybegynder
06. marts 2011 - 19:33 Der er 31 kommentarer og
1 løsning

Problemer med at splitte et xml schema i to

Jeg troede, jeg havde fået det til at være valid, men mine problemer skyldtes forkert opslitning af et ekisterende skema.

Er der nogen, der kan splitte dette skema op i to dvs. et Person schema og et Car schema.

--------------------------------------
<xs:schema elementFormDefault='qualified' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
  <xs:element name='Person' nillable='true' type='Person' />
  <xs:complexType name='Person'>
    <xs:sequence>
      <xs:element minOccurs='1' maxOccurs='1' name='Id' type='xs:long' />
      <xs:element minOccurs='0' maxOccurs='1' name='FirstName' type='xs:string' />
      <xs:element minOccurs='0' maxOccurs='1' name='LastName' type='xs:string' />
      <xs:element minOccurs='1' maxOccurs='1' name='Age' type='xs:int' />
      <xs:element minOccurs='1' maxOccurs='1' name='Gender' type='Gender' />
      <xs:element minOccurs='0' maxOccurs='1' name='Cars' type='ArrayOfCar' />
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name='Gender'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value='Male' />
      <xs:enumeration value='Female' />
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name='ArrayOfCar'>
    <xs:sequence>
      <xs:element minOccurs='0' maxOccurs='unbounded' name='Car' nillable='true' type='Car' />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name='Car'>
    <xs:sequence>
      <xs:element minOccurs='1' maxOccurs='1' name='Id' type='xs:long' />
      <xs:element minOccurs='0' maxOccurs='1' name='Name' type='xs:string' />
      <xs:element minOccurs='0' maxOccurs='1' name='Model' type='xs:string' />
      <xs:element minOccurs='1' maxOccurs='1' name='Year' type='xs:int' />
      <xs:element minOccurs='1' maxOccurs='1' name='Colour' type='Colour' />
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name='Colour'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value='Green' />
      <xs:enumeration value='Blue' />
      <xs:enumeration value='White' />
      <xs:enumeration value='Black' />
      <xs:enumeration value='Red' />
      <xs:enumeration value='Silver' />
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
------------------------------------------------------------------

Person schema skal naturlivis inkludere Car schema'et.
Avatar billede CodingJoe Nybegynder
06. marts 2011 - 19:35 #1
Jeg har keglet rundt i targetNamespace ...og troede jeg fik det til at virke...er der muligvis en måde at gøre det på i xmlSpy eller et andet værktøj?
Avatar billede arne_v Ekspert
06. marts 2011 - 21:26 #2
XML Schema har include til at inkludere et andet skema og import til at importere fra et andet skema.
Avatar billede arne_v Ekspert
06. marts 2011 - 21:27 #3
<xs:include schemaLocation="foobar.xsd"/>
Avatar billede CodingJoe Nybegynder
06. marts 2011 - 22:02 #4
Ja, jeg har forsøgt...men det så ud som om det virkede men...det virkede ikke helt alligevel...

Smider min version ind her...

Person.xsd
-------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.mitsite.dk/schema/Person" xmlns:ns1="http://www.mitsite.dk/schema/Car" targetNamespace="http://www.mitsite.dk/schema/Person" elementFormDefault="qualified">
  <xs:import namespace="http://www.mitsite.dk/schema/Car" schemaLocation="Car.xsd"/>
  <xs:element name="Person" type="Person" nillable="true"/>
  <xs:complexType name="Person">
    <xs:sequence>
      <xs:element name="Id" type="xs:long"/>
      <xs:element name="FirstName" type="xs:string" minOccurs="0"/>
      <xs:element name="LastName" type="xs:string" minOccurs="0"/>
      <xs:element name="Age" type="xs:int"/>
      <xs:element name="Gender" type="Gender"/>
      <xs:element name="Cars" type="ArrayOfCar" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="Gender">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Male"/>
      <xs:enumeration value="Female"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="ArrayOfCar">
    <xs:sequence>
      <xs:element name="Car" type="ns1:Car" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>
-------------------------------------------------------------------
Car.xsd
-------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.mitsite.dk/schema/Car" targetNamespace="http://www.mitsite.dk/schema/Car" elementFormDefault="qualified">
  <xs:element name="Car" type="Car" nillable="true"/>
  <xs:complexType name="Car">
    <xs:sequence>
      <xs:element name="Id" type="xs:long"/>
      <xs:element name="Name" type="xs:string" minOccurs="0"/>
      <xs:element name="Model" type="xs:string" minOccurs="0"/>
      <xs:element name="Year" type="xs:int"/>
      <xs:element name="Colour" type="Colour"/>
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="Colour">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Green"/>
      <xs:enumeration value="Blue"/>
      <xs:enumeration value="White"/>
      <xs:enumeration value="Black"/>
      <xs:enumeration value="Red"/>
      <xs:enumeration value="Silver"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
Avatar billede arne_v Ekspert
06. marts 2011 - 22:48 #5
Her er en version som virker:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
          xmlns:ns0="http://www.mitsite.dk/schema/Person"
          xmlns:ns1="http://www.mitsite.dk/schema/Car"
          targetNamespace="http://www.mitsite.dk/schema/Person"
          elementFormDefault="qualified">
  <xs:import namespace="http://www.mitsite.dk/schema/Car" schemaLocation="Car.xsd"/>
  <xs:element name="Person" type="ns0:Person" nillable="true"/>
  <xs:complexType name="Person">
    <xs:sequence>
      <xs:element name="Id" type="xs:long"/>
      <xs:element name="FirstName" type="xs:string" minOccurs="0"/>
      <xs:element name="LastName" type="xs:string" minOccurs="0"/>
      <xs:element name="Age" type="xs:int"/>
      <xs:element name="Gender" type="ns0:Gender"/>
      <xs:element name="Cars" type="ns1:ArrayOfCar" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="Gender">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Male"/>
      <xs:enumeration value="Female"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>


<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
          xmlns:ns0="http://www.mitsite.dk/schema/Car"
          targetNamespace="http://www.mitsite.dk/schema/Car"
          elementFormDefault="qualified">
  <xs:complexType name="ArrayOfCar">
    <xs:sequence>
      <xs:element name="Car" type="ns0:Car" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="Car">
    <xs:sequence>
      <xs:element name="Id" type="xs:long"/>
      <xs:element name="Name" type="xs:string" minOccurs="0"/>
      <xs:element name="Model" type="xs:string" minOccurs="0"/>
      <xs:element name="Year" type="xs:int"/>
      <xs:element name="Colour" type="ns0:Colour"/>
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="Colour">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Green"/>
      <xs:enumeration value="Blue"/>
      <xs:enumeration value="White"/>
      <xs:enumeration value="Black"/>
      <xs:enumeration value="Red"/>
      <xs:enumeration value="Silver"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>


<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.mitsite.dk/schema/Person"
        xsi:schemaLocation="http://www.mitsite.dk/schema/Person Person.xsd">
    <Id>123</Id>
    <FirstName>xxx</FirstName>
    <LastName>xxxxx</LastName>
    <Age>23</Age>
    <Gender>Male</Gender>
    <Cars>
        <Car xmlns="http://www.mitsite.dk/schema/Car">
            <Id>1</Id>
            <Name>xxx</Name>
            <Model>xxx</Model>
            <Year>2010</Year>
            <Colour>Red</Colour>
        </Car>
    </Cars>
</Person>
Avatar billede arne_v Ekspert
06. marts 2011 - 22:48 #6
Jeg har kun ændret lidt småting her og der.
Avatar billede CodingJoe Nybegynder
06. marts 2011 - 23:01 #7
Hmmm så jeg var ikke langt fra sandheden :s
...kan jeg se.. tester lige...men er sikker på det virker nu...smid bare et svar ind :)

...xsd driver mig hurtigt til vanvid...mon du brugte et værktøj? :)
Avatar billede CodingJoe Nybegynder
06. marts 2011 - 23:02 #8
Kan se mine enums har fået et ns0: prefix...
Avatar billede arne_v Ekspert
06. marts 2011 - 23:12 #9
Jeg har brugt eksplicit namespace i skemaerne og kun default namespace i selve XML'en.

Det gør det lidt nemmere.
Avatar billede arne_v Ekspert
06. marts 2011 - 23:13 #10
Lidt afhængig af problem stillingen kunne du have includet Car.xsd ind i Person.xsd i samme namespace og sparet det skift af namespace i XML'en.
Avatar billede arne_v Ekspert
06. marts 2011 - 23:14 #11
Jeg bruger primært jEdit til at arbejde med XML og skemaer.

Enkelte gange supplerer jeg med:
  XML Copy Editor
Avatar billede arne_v Ekspert
06. marts 2011 - 23:15 #12
og et svar
Avatar billede CodingJoe Nybegynder
06. marts 2011 - 23:18 #13
Hmmmm får denne fejl...mon det fordi jeg laver en 'schemaSet.Compile();'

Det globale element 'http://www.mitsite.dk/schema/Person:Person' er allerede blevet erklæret.

Her er lidt kode for at give dig en ide...

var settings = new XmlReaderSettings();
var schemaSet = new XmlSchemaSet();

schemaSet.Add(null, @"C:\Documents\Work\foo\Skemaer\Person.xsd");
schemaSet.Add(null, @"C:\Documents\Work\foo\Skemaer\Skemaer\Car.xsd");

schemaSet.Compile();
settings.Schemas.Add(schemaSet);
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema | XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += ValidationCallBack;

...
...

Fejler ved schemaSet.Compile();
Avatar billede CodingJoe Nybegynder
06. marts 2011 - 23:30 #14
Argh!

forkert fejlbesked... fejlen er denne:

'Skemaoplysningerne til elementet 'Person' blev ikke fundet.' (sorry fordi den er på dk)..

Men fejlen kommer, når jeg matcher skemaerne mod min xml som bliver læst ind som en streng....

var settings = new XmlReaderSettings();
var schemaSet = new XmlSchemaSet();

schemaSet.Add(null, @"C:\Documents\Work\foo\Skemaer\Person.xsd");
schemaSet.Add(null, @"C:\Documents\Work\foo\Skemaer\Skemaer\Car.xsd");

schemaSet.Compile();
settings.Schemas.Add(schemaSet);
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema | XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += ValidationCallBack;

var document = new XmlDocument();
document.Load(XmlReader.Create(new StringReader(minXmlStreng)));
var rdr = XmlReader.Create(new StringReader(document.InnerXml), settings);
while (rdr.Read()) { }
return true;
Avatar billede arne_v Ekspert
06. marts 2011 - 23:52 #15
Du skal enten angive skema placering i din kode eller angive den i XML og XSD - ikke begge dele.

schemaSet.Add(null, @"C:\Documents\Work\foo\Skemaer\Person.xsd");
schemaSet.Add(null, @"C:\Documents\Work\foo\Skemaer\Skemaer\Car.xsd");

med 2 forskellige dirs ser mærkelig ud.
Avatar billede CodingJoe Nybegynder
06. marts 2011 - 23:53 #16
Ahhh kan se min xml skal beriges med de krævede namespaces...kom forbi person...nu driller car lidt...

Elementet 'Cars' i navneområdet 'http://www.mitsite.dk/schema/Person' har et ugyldigt underordnet element 'Car' i navneområdet 'http://www.mitsite.dk/schema/Car'. Liste over elementer, der kan forventes: 'Car' i navneområdet 'http://www.mitsite.dk/schema/Car'.

kan være en taste fejl da url bliver vist som links herinde :S
Avatar billede CodingJoe Nybegynder
06. marts 2011 - 23:54 #17
Ups...de ligger ved siden af hinanden...

schemaSet.Add(null, @"C:\Documents\Work\foo\Skemaer\Person.xsd");
schemaSet.Add(null, @"C:\Documents\Work\foo\Skemaer\Car.xsd");

bare en copy paste fejl... :S
Avatar billede CodingJoe Nybegynder
06. marts 2011 - 23:57 #18
Den sluger det igennem...uden problem..dog har jeg introduceret et deserialiserings problem et andet sted...sikker pga. namespaces i min xml streng...
Avatar billede arne_v Ekspert
07. marts 2011 - 00:00 #19
Hvis du skal bruge XML serialisering/deserialisering - kan du så ikke generere dine skemaer?
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 00:04 #20
Ideen er at jeg modtager noget xml fra et legacy system...og for at sikre at de ikke laver 'breaking changes' i vores kode, vil jeg gerne have dem til at sende skemaet med som en del af deres xml svar. Jeg splitter data og skema...validere data i forhold til skema / skemaerne...herefter deserialisere jeg det...

...men nu virker skemaerne fint...dog kan jeg ikke deserialisere mit data til et c# objekt mere :(
Avatar billede arne_v Ekspert
07. marts 2011 - 00:07 #21
Prøv og generer data klasser udfra skema så og sammenlign med de data klasser du har.

Eller prøv og serialiser med dem og se hvordan XML adskiller sig fra det du får.
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 00:08 #22
Jeg får denne fejl:

{"<Person xmlns='http://www.mitsite.dk/schema/Person'> var ikke forventet."}
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 00:17 #23
De askiller sig på namespaces:

<Person xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns='http://www.mitsite.dk/schema/Person'>

og under Car
<Car xmlns='http://www.mitsite.dk/schema/Car'>

uden dem...deserialserer min kode det fint...
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 00:18 #24
Måske kan man fjerne det eksplicit ns i skemaerne..
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 00:30 #25
Fandt lige ud af at jeg kan dekorere min klasse med følgende:
[Serializable]
[DataContract]
[XmlRoot(ElementName = "Person", DataType = "Person", IsNullable = true, Namespace = "http://www.mitsite.dk/schema/Person")]
public class Person {
...
...
}
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 00:31 #26
Success!!!!

Tak for hjælpen :D
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 00:31 #27
Car klassen skulle ligeledes dekoreres...
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 00:33 #28
Damn...bilerne bliver ikke deserialiseret kun person :S

Jeg finder lige ud af det....
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 01:29 #29
Fandt det aldrig...så tæt på...og så er der issues med at deserialisere et collection felt...

alternativt må jeg fjerne alle forekomster af xmlns vha. regexp :S
...selvom det lyder ret grimt...
Avatar billede arne_v Ekspert
07. marts 2011 - 01:36 #30
Det burde der ikke være.

Har det collection felt en property med get og set?
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 02:06 #31
Endte med at bruge et regex til at fjerne min namespaces.

Virker grimt...men betyder ikke noget, da jeg er interesseret i indholdet..

const string pattern = "xmlns=\\\".+\\\"";
var regXml = new Regex(pattern);
string res = regXml.Replace(xml, "");
Avatar billede CodingJoe Nybegynder
07. marts 2011 - 02:10 #32
Ja...

Endte med at bruge et regex til at fjerne xmlns fra min xml streng...det gjorde tricket...virker lidt grimt...

const string pattern = "xmlns=\\\".+\\\"";
var regXml = new Regex(pattern);
string res = regXml.Replace(xml, "");

Det gør egentligt ikke noget, da jeg kun er interesseret i data...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester