Co elementFormDefault robi w XSD?

88

Co robi elementFormDefaulti kiedy powinno być używane?

Więc znalazłem kilka definicji elementFormDefaultwartości:

wykwalifikowanych - elementy i atrybuty są w targetNamespace schematu

niekwalifikowany - elementy i atrybuty nie mają przestrzeni nazw

Z tej definicji myślę więc, że jeśli schemat jest ustawiony jako kwalifikowany, to dlaczego należy poprzedzić typ przestrzenią nazw? A jakie są scenariusze, w których mógłbyś mieć jeden ustawiony jako niewykwalifikowany w tej sprawie? Próbowałem googlować, ale dostałem tylko kilka stron W3C, które były niezwykle trudne do zrozumienia.

To jest plik, z którym teraz pracuję, dlaczego muszę deklarować typ, jak target:TypeAssignmentswtedy, gdy deklaruję, że targetNamespacejest taki sam jak xmlns:target?

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:target="http://www.levijackson.net/web340/ns"
        targetNamespace="http://www.levijackson.net/web340/ns" 
        elementFormDefault="qualified">
  <element name="assignments">
    <complexType>
      <sequence>
        <element name="assignments" type="target:TypeAssignments"
                 minOccurs="1" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>
  <complexType name="TypeAssignments">
    <sequence>
      <element name="assignment" type="target:assignmentInfo"
               minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
  </complexType>
  <complexType name="assignmentInfo">
    <sequence>
      <element name="name" type="string"/>
      <element name="page" type="target:TypePage"/>
      <element name="file" type="target:TypeFile" 
               minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
    <attribute name="id" type="string" use="required"/>
  </complexType>
  <simpleType name="TypePage">
    <restriction base="integer">
      <minInclusive value="50" />
      <maxInclusive value="498" />
    </restriction>
  </simpleType>
  <simpleType name="TypeFile">
    <restriction base="string">
      <enumeration value=".xml" />
      <enumeration value=".dtd" />
      <enumeration value=".xsd" />
    </restriction>
  </simpleType>
</schema>
Levi
źródło

Odpowiedzi:

71

ElementFormDefault nie ma nic wspólnego z przestrzenią nazw typów w schemacie, chodzi o przestrzenie nazw elementów w dokumentach XML, które są zgodne ze schematem.

Oto odpowiednia sekcja specyfikacji:

Element Declaration Schema

Component Property  {target namespace}
Representation      If form is present and its ·actual value· is qualified, 
                    or if form is absent and the ·actual value· of 
                    elementFormDefault on the <schema> ancestor is qualified, 
                    then the ·actual value· of the targetNamespace [attribute]
                    of the parent <schema> element information item, or 
                    ·absent· if there is none, otherwise ·absent·.

Oznacza to, że targetNamespace zadeklarowany na początku schematu ma zastosowanie tylko do elementów w dokumencie XML zgodnym ze schematem, jeśli elementFormDefault jest „kwalifikowany” lub element jest jawnie zadeklarowany w schemacie jako mający form = „qualified” .

Na przykład: Jeśli elementFormDefault jest niekwalifikowany -

<element name="name" type="string" form="qualified"></element>
<element name="page" type="target:TypePage"></element>

oczekuje, że elementy „name” będą znajdować się w targetNamespace, a elementy „page” w pustej przestrzeni nazw.

Aby zaoszczędzić na konieczności umieszczania form = "qualified" w każdej deklaracji elementu, określenie elementFormDefault = "qualified" oznacza, że ​​targetNamespace ma zastosowanie do każdego elementu, chyba że zostanie nadpisane przez umieszczenie form = "unqualified" w deklaracji elementu.

Alohci
źródło
Chociaż ta odpowiedź odnosi się do specyfikacji, nie interpretuje jej poprawnie. Elementy zdefiniowane lokalnie nadal znajdują się w targetNamespace i nigdy nie znajdują się w pustej przestrzeni nazw. elementFormDefault to po prostu przełącznik, który określa, czy przestrzeń nazw ma kwalifikować je w instancji.
Ihe Onwuka
1
@Ihe, to nie jest poprawne: lub w każdym razie może to zmylić ludzi. Jeśli deklaracja elementu lokalnego nie ma form = qualified, to właściwość {target namespace} komponentu schematu deklaracji elementu jest „nieobecna”, a to oznacza, że ​​właściwość URI przestrzeni nazw instancji elementu również musi być „nieobecna”.
Michael Kay
@MichaelKay Dla mnie to jeszcze bardziej zagmatwane. Pytanie brzmi, czy strona przykładowa znajduje się w pustej przestrzeni nazw, ponieważ jeśli tak jest, dlaczego specyfikacja nie mówi po prostu, że ustawienie elementFormDefault = unqualified umieszcza lokalnie zdefiniowane elementy w pustej przestrzeni nazw. Mówi, że strona nie powinna być kwalifikowana do przestrzeni nazw w instancji, to samo co mówienie, że strona nie jest w przestrzeni nazw, ponieważ to dlatego specyfikacja nie mówi tego po prostu i dlaczego schemat z docelową przestrzenią nazw sprawdza rzeczy, które nie są w tej przestrzeni nazw?
Ihe Onwuka
1
Nie „po prostu tak mówi”, ponieważ opisujesz to bardzo nieformalnie: wyrażenie „umieszczanie elementu w pustej przestrzeni nazw” nie używa terminologii specyfikacji XSD; specyfikacja woli używać znacznie staranniejszej terminologii, co często utrudnia czytanie, ale w końcu jest o wiele bardziej precyzyjna.
Michael Kay
1
Jeśli o mnie chodzi, to poprawna odpowiedź, tak jak napisano.
Michael Kay
60

Rozważmy następujący ComplexType AuthorTypeużywany przez authorelement

<xsd:complexType name="AuthorType">
  <!-- compositor goes here -->
  <xsd:sequence>
     <xsd:element name="name" type="xsd:string"/>
     <xsd:element name="phone" type="tns:Phone"/>
  </xsd:sequence>
  <xsd:attribute name="id" type="tns:AuthorId"/>
</xsd:complexType>
<xsd:element name="author" type="tns:AuthorType"/>

Jeśli elementFormDefault="unqualified"

to następujące wystąpienie XML jest prawidłowe

<x:author xmlns:x="http://example.org/publishing">
   <name>Aaron Skonnard</name>
   <phone>(801)390-4552</phone>
</x:author>

atrybut nazwiska autora jest dozwolony bez określania przestrzeni nazw (niekwalifikowany). Wszelkie elementy, które są częścią, <xsd:complexType>są traktowane jako lokalne dla complexType.

Jeśli elementFormDefault="qualified"

wtedy instancja powinna mieć kwalifikowane elementy lokalne

<x:author xmlns:x="http://example.org/publishing">
   <x:name>Aaron Skonnard</name>
   <x:phone>(801)390-4552</phone>
</x:author>

proszę zapoznać się z tym linkiem, aby uzyskać więcej informacji

Girish
źródło
55

Nowa, szczegółowa odpowiedź i wyjaśnienie starego, często zadawanego pytania ...

Krótka odpowiedź : jeśli nie dodasz elementFormDefault="qualified"do xsd:schema, unqualifiedwartość domyślna oznacza, że ​​lokalnie zadeklarowane elementy nie znajdują się w przestrzeni nazw .

Istnieje wiele nieporozumień dotyczących tego elementFormDefault, co powoduje, ale można to szybko wyjaśnić za pomocą krótkiego przykładu ...

Uproszczona wersja Twojego XSD:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:target="http://www.levijackson.net/web340/ns"
        targetNamespace="http://www.levijackson.net/web340/ns">
  <element name="assignments">
    <complexType>
      <sequence>
        <element name="assignment" type="target:assignmentInfo" 
                 minOccurs="1" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>
  <complexType name="assignmentInfo">
    <sequence>
      <element name="name" type="string"/>
    </sequence>
    <attribute name="id" type="string" use="required"/>
  </complexType>
</schema>

Kluczowe punkty:

  • assignmentElement jest lokalnie zdefiniowane.
  • Elementy zdefiniowane lokalnie w XSD domyślnie nie znajdują się w przestrzeni nazw.
    • Dzieje się tak, ponieważ wartość domyślna elementFormDefaultto unqualified.
    • Jest to prawdopodobnie błąd projektowy twórców XSD.
    • Standardową praktyką jest używanie zawsze elementFormDefault="qualified" tak, aby znajdowało assignmentsię w docelowej przestrzeni nazw, jak można się spodziewać.
  • Jest to rzadko używany formatrybut w xs:elementdeklaracjach, dla którego elementFormDefaultustalane są wartości domyślne.

Pozornie poprawny XML

Wygląda na to, że ten XML powinien być prawidłowy zgodnie z powyższym XSD:

<assignments xmlns="http://www.levijackson.net/web340/ns"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.levijackson.net/web340/ns try.xsd">
  <assignment id="a1">
    <name>John</name>
  </assignment>
</assignments>

Ogłoszenie:

  • Domyślna przestrzeń nazw w assignmentsmiejscach assignmentsi wszystkie jej elementy podrzędne w domyślnej przestrzeni nazw ( http://www.levijackson.net/web340/ns).

Kłopotliwy błąd walidacji

Pomimo tego, że wygląda na poprawny, powyższy kod XML powoduje następujący mylący błąd weryfikacji:

[Błąd] try.xml: 4: 23: cvc-complex-type.2.4.a: Znaleziono nieprawidłową treść zaczynającą się od elementu „przypisanie”. Oczekiwany jest jeden z „{przypisanie}”.

Uwagi:

  • Nie byłbyś pierwszym programistą, który przeklął tę diagnostykę, która wydaje się mówić, że treść jest nieprawidłowa, ponieważ oczekiwano, że znajdzie assignmentelement, ale faktycznie znalazł assignmentelement. ( WTF )
  • Co to naprawdę oznacza: „ {i }wokół” assignmentoznacza, że ​​walidacja nie oczekiwała tutaj assignment żadnej przestrzeni nazw . Niestety, kiedy mówi, że znalazł assignmentelement, nie wspomina, że ​​znalazł go w domyślnej przestrzeni nazw, która różni się od żadnej przestrzeni nazw.

Rozwiązanie

  • Przez większość czasu: dodaj elementFormDefault="qualified"do xsd:schemaelementu XSD. Oznacza to, że prawidłowy kod XML musi umieszczać elementy w docelowej przestrzeni nazw, gdy jest zadeklarowany lokalnie w XSD; w przeciwnym razie poprawny kod XML musi umieszczać lokalnie zadeklarowane elementy w żadnej przestrzeni nazw.
  • Niewielka mniejszość czasu: Zmień XML, aby był zgodny z wymaganiami XSD, które assignmentnie znajdują się w przestrzeni nazw. Można to osiągnąć na przykład poprzez dodanie xmlns=""do assignmentelementu.

Kredyty: Dziękuję Michaelowi Kay za pomocną opinię na temat tej odpowiedzi.

kjhughes
źródło
12

W przypadku elementu elementFormDefault należy zauważyć, że ma on zastosowanie do elementów zdefiniowanych lokalnie , zazwyczaj nazwanych elementów w bloku complexType, w przeciwieństwie do elementów globalnych zdefiniowanych na najwyższym poziomie schematu. Dzięki elementFormDefault = "qualified" można adresować elementy lokalne w schemacie z poziomu dokumentu xml, używając docelowej przestrzeni nazw schematu jako domyślnej przestrzeni nazw dokumentu.

W praktyce użyj elementu elementFormDefault = "qualified", aby móc deklarować elementy w zagnieżdżonych blokach, w przeciwnym razie będziesz musiał zadeklarować wszystkie elementy na najwyższym poziomie i odwołać się do nich w schemacie w elementach zagnieżdżonych przy użyciu atrybutu ref, co spowoduje znacznie mniej zwarty schemat.

Ten fragment w XML Schema Primer mówi o tym: http://www.w3.org/TR/xmlschema-0/#NS

stephan f
źródło
Nieznaczne wyjaśnienie, co wygląda na najdokładniejszą odpowiedź. W przypadku elementu elementFormDefault = qualified, przestrzeń nazw musi kwalifikować elementy lokalne w intance. Gdy jest ustawiony na niekwalifikowany, nie możesz ich kwalifikować przez przestrzeń nazw.
Ihe Onwuka
6

ElementFormDefault = "Qualified" służy do kontrolowania użycia przestrzeni nazw w dokumentach instancji XML (plik .xml), a nie przestrzeni nazw w samym dokumencie schematu (plik .xsd).

Określając elementFormDefault = "qualified", wymuszamy deklarację przestrzeni nazw, która ma być używana w dokumentach walidowanych za pomocą tego schematu.

Powszechną praktyką jest określanie tej wartości, aby zadeklarować, że elementy powinny być kwalifikowane, a nie niekwalifikowane. Jednak ponieważ atrybutFormDefault = "niekwalifikowany" jest wartością domyślną, nie trzeba jej określać w dokumencie schematu, jeśli nie chce się kwalifikować przestrzeni nazw.

Feri
źródło
elementFormDefault ma zastosowanie tylko do elementów zdefiniowanych lokalnie. Niezależnie od tego elementy globalne muszą być kwalifikowane w przestrzeni nazw.
Ihe Onwuka
0

Zauważyłem, że XMLSpy (przynajmniej wersja 2011) wymaga zdefiniowania targetNameSpace, jeśli używany jest elementFormDefault = "qualified". W przeciwnym razie nie zostanie zweryfikowany. Nie będzie też generować plików XML z prefiksami przestrzeni nazw

Neal
źródło