Что делает elementFormDefault в XSD?

88

Что делает elementFormDefaultи когда нужно использовать?

Итак, я нашел несколько определений для elementFormDefaultзначений:

квалифицированный - элементы и атрибуты находятся в targetNamespace схемы

unqualified - элементы и атрибуты не имеют пространства имен

Итак, исходя из этого определения, я мог бы подумать, что если схема настроена как квалифицированная, то почему вы должны префикс типа с пространством имен? И каковы сценарии, при которых у вас даже был бы один набор неквалифицированных в этом отношении? Я пробовал поискать в Google, но все, что у меня было, это пара страниц W3C, которые было очень трудно понять.

Это файл, с которым я работаю прямо сейчас, зачем мне объявлять тип, как target:TypeAssignmentsесли бы я объявлял его targetNamespaceтаким же, как 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>
Леви
источник

Ответы:

71

ElementFormDefault не имеет ничего общего с пространствами имен типов в схеме, это касается пространств имен элементов в XML-документах, которые соответствуют схеме.

Вот соответствующий раздел спецификации:

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·.

Это означает, что targetNamespace, который вы объявили в верхней части схемы, применяется только к элементам в XML-документе, совместимом со схемой, если либо elementFormDefault является "квалифицированным", либо элемент явно объявлен в схеме как имеющий form = "квалифицированный" .

Например: Если elementFormDefault неквалифицирован -

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

будет ожидать, что элементы «name» будут в targetNamespace, а элементы «page» - в пустом пространстве имен.

Чтобы избавить вас от необходимости указывать form = "квалифицированный" в каждом объявлении элемента, указание elementFormDefault = "квалифицированный" означает, что targetNamespace применяется к каждому элементу, если оно не отменено путем помещения form = "unqualified" в объявление элемента.

Алохчи
источник
Хотя этот ответ относится к спецификации, он не интерпретирует его правильно. Локально определенные элементы все еще находятся в targetNamespace и никогда не находятся в пустом пространстве имен. elementFormDefault - это просто переключатель, который указывает, должно ли пространство имен квалифицировать их в экземпляре.
Ихе Онвука,
1
@Ihe, это неверно: во всяком случае, это может сбивать людей с толку. Если в объявлении локального элемента отсутствует form = квалифицированный, тогда свойство {target namespace} компонента схемы объявления элемента "отсутствует", и это означает, что свойство URI пространства имен экземпляра элемента также должно быть "отсутствующим".
Майкл Кей
@MichaelKay Меня это еще больше сбивает с толку. Вопрос в том, находится ли страница в примере в пустом пространстве имен, потому что, если именно поэтому в спецификации просто не сказано, что установка elementFormDefault = unqualified помещает локально определенные элементы в пустое пространство имен. Говорит, что страница не должна быть квалифицирована в пространстве имен в экземпляре, то же самое, что сказать, что страница не находится в пространстве имен, потому что это то, почему в спецификации просто не говорится об этом и почему схема с targetNamespace проверяет то, что не в этом пространстве имен?
Ихе Онвука,
1
Он не «просто говорит это», потому что вы описываете это очень неформально: фраза «помещение элемента в пустое пространство имен» не использует терминологию спецификации XSD; спецификация предпочитает использовать более точную терминологию, которая часто затрудняет чтение, но в итоге оказывается более точной.
Майкл Кей
1
Насколько я понимаю, это правильный ответ, как написано.
Майкл Кей,
60

Рассмотрим следующий ComplexType, AuthorTypeиспользуемый authorэлементом

<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"/>

Если elementFormDefault="unqualified"

то следующий экземпляр XML действителен

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

Атрибут имени авторов разрешен без указания пространства имен (неквалифицированный). Любые элементы, входящие в состав <xsd:complexType>, считаются локальными для complexType.

если elementFormDefault="qualified"

тогда экземпляр должен иметь квалифицированные локальные элементы

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

пожалуйста, обратитесь по этой ссылке для получения более подробной информации

Гириш
источник
55

Новый, подробный ответ и объяснение на старый, часто задаваемый вопрос ...

Краткий ответ : если вы не добавляете elementFormDefault="qualified"к xsd:schema, unqualifiedзначение по умолчанию означает, что локально объявленные элементы не находятся в пространстве имен .

Есть много недоразумений относительно того, что elementFormDefault , делает, но это можно быстро прояснить с помощью небольшого примера ...

Оптимизированная версия вашего 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>

Ключевые моменты:

  • assignmentЭлемент локально определен.
  • Элементы, локально определенные в XSD, по умолчанию не находятся в пространстве имен.
    • Это потому , что значение по умолчанию для elementFormDefaultявляетсяunqualified .
    • Возможно, это ошибочный дизайн создателей XSD.
    • Стандартная практика - всегда использовать, elementFormDefault="qualified" чтобы assignmentон находился в целевом пространстве имен, как и следовало ожидать.
  • Это редко используемый formатрибут в xs:elementобъявлениях, для которых elementFormDefaultустанавливаются значения по умолчанию.

На первый взгляд действительный XML

Этот XML выглядит так, как будто он должен быть действительным в соответствии с приведенным выше 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>

Уведомление:

  • Пространство имен по умолчанию для assignmentsмест assignmentsи всех его потомков в пространстве имен по умолчанию ( http://www.levijackson.net/web340/ns).

Непонятная ошибка проверки

Несмотря на то, что приведенный выше XML выглядит корректным, он дает следующую сбивающую с толку ошибку проверки:

[Ошибка] try.xml: 4: 23: cvc-complex-type.2.4.a: Неверный контент был обнаружен, начиная с элемента 'assignment'. Ожидается одно из "{assignment}".

Примечания:

  • Вы не были бы первым разработчиком, который проклинает эту диагностику, которая, кажется, говорит, что контент недействителен, потому что он ожидал найти assignmentэлемент, но на самом деле нашел assignmentэлемент. ( WTF )
  • Что это на самом деле означает: {и }вокруг assignmentозначает, что здесь не ожидалось проверки assignment в пространстве имен . К сожалению, когда он говорит, что нашел assignmentэлемент, он не упоминает, что нашел его в пространстве имен по умолчанию, которое отличается от пространства имен no.

Решение

  • В большинстве случаев: добавьте elementFormDefault="qualified"кxsd:schema элементу XSD. Это означает, что действительный XML должен помещать элементы в целевое пространство имен при локальном объявлении в XSD; в противном случае действительный XML не должен помещать локально объявленные элементы в пространство имен.
  • Крошечное меньшинство времени: измените XML, чтобы он соответствовал требованиям XSD, которые не assignmentдолжны находиться в пространстве имен. Этого можно добиться, например, добавив xmlns=""к assignmentэлементу.

Кредиты: Спасибо Майклу Кею за полезный отзыв на этот ответ.

Kjhughes
источник
12

Важно отметить, что elementFormDefault применяется к локально определенным элементам, обычно именованным элементам внутри блока complexType, в отличие от глобальных элементов, определенных на верхнем уровне схемы. С elementFormDefault = "квалифицированный" вы можете адресовать локальные элементы в схеме изнутри XML-документа, используя целевое пространство имен схемы в качестве пространства имен документа по умолчанию.

На практике используйте elementFormDefault = "квалифицированный", чтобы иметь возможность объявлять элементы во вложенных блоках, в противном случае вам придется объявить все элементы на верхнем уровне и ссылаться на них в схеме во вложенных элементах с помощью атрибута ref, что приведет к гораздо менее компактная схема.

Об этом говорится в этом фрагменте XML Schema Primer: http://www.w3.org/TR/xmlschema-0/#NS

Стефан Ф
источник
Небольшое уточнение наиболее точного ответа. С elementFormDefault = квалифицированным вы должны указать пространство имен локальных элементов в интансе. Если для него установлено значение unqualified, вы не должны квалифицировать их в пространстве имен.
Ихе Онвука,
6

elementFormDefault = "квалифицированный" используется для управления использованием пространств имен в документах экземпляров XML (файл .xml), а не пространства имен в самом документе схемы (файл .xsd).

Указав elementFormDefault = "квалифицированный", мы принудительно используем объявление пространства имен в документах, проверенных с помощью этой схемы.

Это обычная практика указывать это значение, чтобы объявить, что элементы должны быть квалифицированными, а не неквалифицированными. Однако, поскольку attributeFormDefault = "unqualified" является значением по умолчанию, его не нужно указывать в документе схемы, если не требуется уточнять пространства имен.

Фери
источник
elementFormDefault применяется только к локально определенным элементам. В любом случае глобальные элементы должны быть квалифицированы в пространстве имен.
Ихе Онвука,
0

Я заметил, что XMLSpy (по крайней мере версия 2011 года) требует определенного targetNameSpace, если используется elementFormDefault = "qualified". В противном случае не будет подтверждено. А также не будет генерировать xmls с префиксами пространства имен

Нил
источник