Как расширить схему 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 (такой как этот) и изменить его (добавив свои собственные элементы и изменив требуемые элементы Atom). Это не очень хорошо (я бы больше не расширял Atom, я просто создал бы новую схему), поэтому я надеюсь на лучшее решение.

1 ответ

Решение

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

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

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

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

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

    Генерация регулярного выражения, которое соответствует addr-spec Производство RFC 2822 и, следовательно, обеспечение соблюдения правил спецификации Atom невозможно. (Набор допустимых значений addr-spec не зависит от контекста, а не является регулярным, потому что RFC 2822 комментирует nest.) Аппроксимация его регулярным выражением возможна, но немного трудоемка и подвержена ошибкам, если вы не делаете это систематически. Самое простое решение - последовать примеру схемы 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, который может поддерживаться или не поддерживаться цепочкой инструментов, которую вы надеетесь использовать.

Другие вопросы по тегам