Как расширить схему Atom?

Я разрабатываю XML-поток продуктов, который будет использоваться рядом интернет-магазинов для публикации своих данных о продуктах. Структура этого фида товаров будет основана на стандарте Atom XML, аналогичном фид продуктов Google Atom. Я опубликую XSD-файл, который можно использовать для проверки товарных фидов.

По сути, каждый элемент <entry> будет представлять продукт. Мне нужно будет добавить несколько дочерних элементов к элементу <entry>, который будет содержать такие данные, как цена продукта, стоимость доставки и т. Д.

Проблема заключается в создании файла XSD. Я не уверен, как расширить стандарт Atom таким образом, чтобы можно было добавлять дочерние элементы в <entry>. В настоящее время я просто определяю дополнительные элементы как элементы верхнего уровня, но это не позволяет мне указывать индикаторы возникновения (minOccurs и maxOccurs).

Я хочу указать количество элементов, которые требуются в каждом элементе <entry>. Это могут быть новые элементы, введенные моей схемой (например, элемент <price>, содержащий цену продукта), а также существующие элементы Atom (например, элемент <link>, который определяется Atom, но не является обязательным).

Вот (упрощенная версия) моего текущего product-feed.xsd:

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://example.com/schemas/product-feed"
    xmlns:p="http://example.com/schemas/product-feed"
    xmlns:atom="http://www.w3.org/2005/Atom"
    elementFormDefault="qualified">

  <xs:element name="brand" type="xs:string" />

  <xs:element name="price" type="p:money" />

  <xs:element name="shipping" type="p:money" />

  <xs:complexType name="money">
    <xs:simpleContent>
      <xs:extension base="xs:decimal">
        <xs:attribute name="currency" 
                      type="p:currency" 
                      use="required" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>

  <xs:simpleType name="currency">
    <xs:restriction base="xs:string">
      <xs:enumeration value="EUR" />
      <xs:enumeration value="USD" />
      <xs:enumeration value="GBP" />
    </xs:restriction>
  </xs:simpleType>

</xs:schema>

Вот пример xml-фида:

<?xml version="1.0" encoding="UTF-8"?>

<feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:p="http://example.com/schemas/product-feed"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <title>Example Store</title>
  <link href="http://www.example-store.com/" rel="self" />
  <updated>2014-08-08T10:44:20Z</updated>

  <entry>
    <title>Foo</title>
    <link href="http://www.example-store.com/products/foo.html" />
    <p:price currency="EUR">32.95</p:price>
    <p:shipping currency="EUR">6.75</p:shipping>
  </entry>

  <entry>
    <title>Bar</title>
    <link href="http://www.example-store.com/products/acme-bar.html" />
    <p:brand>Acme</p:brand>
    <p:price currency="EUR">12.50</p:price>
    <p:shipping currency="EUR">6.75</p:shipping>
  </entry>

</feed>

Как я могу расширить схему Atom таким образом, чтобы мои пользовательские элементы были разрешены только внутри элемента <entry>, и чтобы я мог определить, сколько раз они могут встречаться?

Единственное альтернативное решение, которое я могу придумать, - это дублировать файл определения схемы Atom (например, this one) и изменить это (добавить свои собственные элементы и изменить элементы Atom, которые мне нужны). Это не очень хорошо (я бы больше не расширял Atom, я просто создавал бы совершенно новую схему), поэтому я надеюсь на лучшее решение.


person Nic Wortel    schedule 08.08.2014    source источник
comment
Вам просто нужна схема XSD, которая будет проверять ваши данные, или требуется, чтобы она включала некоторую существующую схему XSD для пространства имен Atom? Если последнее, то какую существующую схему XSD для пространства имен Atom вы хотите использовать?   -  person C. M. Sperberg-McQueen    schedule 12.08.2014
comment
Вы говорите, что определение дополнительных элементов как элементов верхнего уровня ... позволяет использовать их где угодно, а не только внутри элемента <entry> таким образом, который предполагает, что вы не хотели бы, чтобы они были действительными за пределами <entry>, отменяя правило схемы Atom, которое они действительны в другом месте. Какие еще дополнительные ограничения по отношению к схеме Atom вы хотите применить? Какие еще требования существуют для схемы, которую вы хотите написать?   -  person C. M. Sperberg-McQueen    schedule 12.08.2014
comment
@ CMSperberg-McQueen, насколько мне известно, не существует авторитетной схемы XSD для стандарта Atom, но я нашел этот. Расширение существующей схемы не является обязательным, но я бы предпочел сделать это вместо того, чтобы дублировать все в моем собственном XSD. И вы правы, Atom допускает дополнительные элементы в нескольких местах. Однако я хочу иметь возможность, например, требовать, чтобы каждый элемент ‹entry› содержал элемент ‹price› (пользовательский элемент, введенный мной) и элемент ‹link› (определенный Atom, но не как требуется). См. Мой обновленный вопрос.   -  person Nic Wortel    schedule 12.08.2014


Ответы (1)


Полный ответ с пояснениями потребует больше времени, чем у меня есть сегодня, но суть решения может быть быстро набросана.

Во-первых, XSD, на который вы указываете, имеет ряд проблем как представление формата Atom, как описано в RFC 4287 < / а>.

  • Он использует повторяющиеся группы выбора для представления групп чередования Relax NG, что означает, что он не применяет какие-либо ограничения мощности схемы ГСЧ спецификации в конструкции Atom person, элементе atom: feed, элементе atom: entry или atomSource. .

    В схеме XSD 1.1 они лучше всего представлены с помощью всех групп. В схеме XSD 1.0 для обеспечения соблюдения минимальных и максимальных ограничений вхождения для отдельных элементов потребуется довольно подробный выбор последовательностей (сами с вложенными группами выбора), что возможно, но несколько утомительно для построения.

  • Он использует шаблон регулярного выражения для адресов электронной почты, который не согласуется ни с прозой спецификации Atom (в которой говорится, что адреса должны соответствовать RFC 2922), ни со схемой RNG (которая использует очень простое выражение ".+@.+".

    Создание регулярного выражения, которое соответствует addr-spec продукции RFC 2822 и, таким образом, обеспечивает соблюдение правил спецификации Atom, невозможно. (Набор допустимых значений addr-spec не зависит от контекста, а не является регулярным, потому что RFC 2822 содержит вложенные комментарии.) Аппроксимация его с помощью регулярного выражения возможна, но требует немного времени и подвержена ошибкам, если вы не делаете это систематически. Самое простое решение - следовать примеру схемы RNG в спецификации Atom и просто требовать строку с хотя бы одним знаком at ни в начале, ни в конце.

Итак, вашим первым шагом будет создание (или поиск) XSD, который лучше отображает грамматику документа Atom.

Тогда у вас есть три варианта:

  • Измените документ схемы (добавив комментарии для описания ваших изменений и указав будущим читателям документ базовой схемы, с которого вы начали), чтобы импортировать ваше пространство имен и добавить определенные элементы, которые вы хотите, в модель содержимого для atom: entry.

    Это имеет то преимущество, что это просто сделать. Его недостаток состоит в том, что связь между вашей модификацией языка Atom и его определением в спецификации Atom настолько ясна, насколько ясны ваши комментарии на естественном языке. Вы беспокоитесь, что в этом случае вы не расширяете язык Atom; Я думаю, что вы расширяете язык Atom, но вы правильно заметили, что вы не делаете этого, расширяя автономную схему для Atom. Это, вероятно, считается недостатком.

  • Используйте xsd: redefine, чтобы переопределить тип элемента atom: entry, ограничив подстановочный знак элементами, которые вы хотите видеть. Ваше переопределение должно быть допустимым ограничением типа, как определено в базовой схеме (но XSD не гарантирует, что соответствующее переопределение соответствующей схемы будет соответствующей схемой, из-за чего ограничения на переопределение кажутся довольно бессмысленными для некоторых пользователей).

    Это имеет то преимущество, что соответствует XSD 1.0; его недостаток состоит в том, что он, вероятно, довольно сложен и подвержен ошибкам (только на прошлой неделе я слышал, как один известный дизайнер документов публично заявил, что ему так и не удалось заставить работать переопределение XSD). У него также есть недостаток, заключающийся в том, что процессоры XSD 1.0, как известно, имеют несовместимые реализации переопределения. (Однако следует отметить, что несоответствия в основном проявляются в ситуациях, связанных с множественным избыточным импортом, включением и переопределением, и не должны проявляться в простой ситуации, которую вы описываете).

  • Если вам доступен XSD 1.1, используйте xsd: override, чтобы соответствующим образом изменить модель содержимого atom: entry.

    Это имеет то преимущество, что ваши изменения хранятся отдельно от базовой схемы, и его проще указать, чем xsd: redefine. Однако для этого требуется XSD 1.1, который может поддерживаться или не поддерживаться цепочкой инструментов, которую вы планируете использовать.

person C. M. Sperberg-McQueen    schedule 12.08.2014
comment
Спасибо за отличный ответ. Я считаю, что моя IDE использует XSD 1.0, и я пока не знаю, какие другие инструменты я буду использовать для проверки XML-каналов, поэтому боюсь, что не могу полагаться на доступность XSD 1.1. Я начинаю сомневаться в том, что расширение Atom действительно стоит всех этих проблем. Мне, вероятно, следует просто создать свою собственную автономную схему, не расширяя Atom. Тем не менее, вы предоставили мне некоторые ценные сведения, большое вам спасибо. - person Nic Wortel; 14.08.2014