Mam dwa XSD, które definiują różne dokumenty. Powiedzmy, że A.xsd definiuje element ElementA jako korzeń, z pewnymi złożonymi regułami. Teraz B.xsd definiuje element ElementB, który powinien używać ElementA gdzieś pomiędzy.

Na przykład chcę, aby plik XML dla ElementB wyglądał tak:

<?xml version="1.0" encoding="utf-8"?>
<ElementB xmlns="http://example.com/namespace/for/ElementB">
  <foo>Bla</foo>
  <bar>Blub</bar>
  <ElementA xmlns="http://example.com/namespace/for/ElementA">
    <!-- ... -->
  </ElementA>
</ElementB>

Wtedy B.xsd może wyglądać tak:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://example.com/namespace/for/ElementB" targetNamespace="http://example.com/namespace/for/ElementB" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="ElementB">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="foo" type="xs:string" />
        <xs:element name="bar" type="xs:string" />

        <!-- And now I want to include ElementA somehow -->
        <xs:element name="ElementA" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Chodzi o to, że tak naprawdę nie chcę klonować specyfikacji ElementA do B.xsd, ponieważ istnieją również dokumenty, które po prostu mają ElementA jako root (tzn. ElementB jest pewnego rodzaju dokumentem-kontenerem).

Jak więc mogę zezwolić na ElementA w ciągu ElementB, jednocześnie całkowicie rozbudowując już istniejący XSD?

23
poke 20 czerwiec 2011, 18:54

2 odpowiedzi

Najlepsza odpowiedź

W rzeczywistości istnieją dwa różne sposoby tworzenia dokumentów schematu XML: <xs:import> i <xs:include>. xs:include jest przeznaczone do użycia, gdy przestrzeń nazw dokumentu zawierającego jest taka sama, jak ta, do której się odwołujemy, więc nie jest to dokładnie to, czego szukasz. xs:import sprawdza się lepiej w sytuacji, gdy trzeba odwołać się do wszystkich (lub podzbioru) elementów w odnośnym schemacie i znajdują się one w innej docelowej przestrzeni nazw. Tutaj jest pytanie dotyczące różnic: Jaka jest różnica między xsd:include i xsd: importować?.

W każdym razie wróćmy do tego konkretnego pytania. To, czego prawdopodobnie chcesz, to coś takiego:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema 
    xmlns="http://example.com/namespace/for/ElementB"
    targetNamespace="http://example.com/namespace/for/ElementB"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    xmlns:ea="http://example.com/namespace/for/ElementA">
 <xs:import namespace="http://example.com/namespace/for/ElementA" schemaLocation="A.xsd" /> 
 <xs:element name="ElementB">
  <xs:complexType>
   <xs:sequence>
    <xs:element name="foo" type="xs:string" />
    <xs:element name="bar" type="xs:string" />
    <!-- This introduces a element named ElementA that uses the ComplexType ea:ElementA defined in A.xsd -->
    <xs:element name="ElementA" type="ea:ElementA" />
   </xs:sequence>
  </xs:complexType>
 </xs:element>
</xs:schema>

Chociaż będziesz potrzebować A.xsd, aby utworzyć złożony typ dla ElementA, którego możesz użyć w B.xsd, jak pokazano.

Ten artykuł zawiera dobre informacje/przykłady i zawiera omówienie niektórych różnych strategii komponowania: http://www .xfront.com/ZeroOneOrManyNamespaces.html

36
Community 23 maj 2017, 15:26
Dziękuję, wygląda całkiem nieźle, spróbuję. Jedno pytanie, skąd pochodzi prefiks przestrzeni nazw ea:? A może name definicja typu dostaje się do A.xsd?
 – 
poke
20 czerwiec 2011, 23:34
Po prostu przewiń w prawo w oknie kodu - jest on wymieniony jako ostatni atrybut w elemencie xs:schema: xmlns:ea="http://example.com/namespace/for/ElementA". Możesz nadać mu dowolny prefiks, tak jak możesz dla domyślnej docelowej przestrzeni nazw (chociaż każdy zawsze wybiera xs lub xsd zgodnie z konwencją).
 – 
daveaglick
20 czerwiec 2011, 23:51
Och, nie zawracałem sobie głowy przewijaniem tak daleko i przegapiłem to, przepraszam xD Również dziękuję za pomoc, spróbuję tego jak najszybciej i opublikuję moje wyniki :)
 – 
poke
21 czerwiec 2011, 00:10
: Ja też jestem w podobnej sytuacji. Ale mój problem polega na tym, że elementB nie ma deklaracji przestrzeni nazw, podczas gdy tylko elemenA ma dekalarację przestrzeni nazw. Więc jak mam to tylko uwzględnić. Ponadto nie ma xsd dla elementu A. Jedyną rzeczą, którą należy sprawdzić, jest to, czy element A zawiera deklarację przestrzeni nazw.
 – 
Ashwin
28 maj 2012, 08:20
Jeśli ElementA ma element podrzędny, powiedz Bazz, wtedy biblioteka walidacji wyświetla błąd w tym "Element 'Bazz': Ten element nie jest oczekiwany". Jaki może być tego powód?
 – 
Jawaid
10 wrzesień 2020, 14:15

Możesz użyć tagu <xsd:import>, aby zaimportować schemat z inną przestrzenią nazw.

0
Bhargav Rao 23 maj 2017, 23:27
2
Czy możesz podać przykład, jak tego użyć w powyższym przykładzie? Twój link tak naprawdę tego nie wyjaśnia...
 – 
poke
20 czerwiec 2011, 20:16