Реализация отношений типа внешнего ключа в схеме XSD - PullRequest
3 голосов
/ 05 марта 2009

Я пытаюсь обернуть голову вокруг XML-схем, и одну вещь, которую я пытаюсь выяснить, - это как создавать схемы реляционных типов, где элемент ссылается на другую, возможно, в другой схеме вообще. Я посмотрел на xsd: key и xsd: keyref, и это похоже на то, что меня интересует, но я не уверен. Первоначально я просто устанавливал атрибуты с типом xs: ID abd xs: IDREF, который, очевидно, не обязательно ссылается на конкретный элемент, насколько я могу судить.

По сути, у меня есть несколько разных xml-файлов, где элементы ссылаются на другие элементы либо в том же файле, либо в других файлах. Это похоже на реляционную базу данных, и я хотел бы использовать ее, но требование состоит в том, чтобы использовать только файлы XML, и поэтому я, по крайней мере, пытаюсь установить здравый смысл some вместо просто кажущихся случайными строк, полагающихся на XML-комментарии, чтобы определить отношения. Он работает для небольших проектов, но, безусловно, не масштабируется.

Есть мысли?

Ответы [ 3 ]

5 голосов
/ 06 марта 2009

Я не знаю ничего внутри XML-схемы, которая позволила бы вам проверять несколько XML-документов друг против друга. В ограничениях xs:id и xs:key (и т. Д.) Вы применяете xpath для применения ограничений. Вы можете перейти к XML-схеме Часть 1: Структуры и немного прокрутить вниз для примера, чтобы увидеть эти ограничения в действии.

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

Допустим, вам нужно проверить Вики, в которой есть много постов, где у каждого поста есть автор, и, возможно, много комментариев, где у каждого комментария также есть автор, и что у вас есть один XML-файл для всех постов, один для всех комментариев, один для всех авторов, и вы хотите проверить ограничения между этими файлами, чтобы каждый пост использовал существующих авторов и комментариев, чтобы каждый комментарий использовал существующих авторов и т. д. Допустим, у вас есть следующие три файла:

Файл /home/username/posts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<posts>
  <post>
    <author name="author1"/>
    <comment id="12345" pos="1"/>
    <comment id="12346" pos="2"/>
    <body>I really like my camera...</body>
  </post>
   ...
</posts>

Файл /home/username/comments.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<comments>
  <comment id="12345" author="kindguy">
    That was a very good post
  </comment>
   ...
</comments>

Файл /home/username/authors.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<authors>
  <author name="kindguy" id="1"/>
  <author name="author1" id="2"/>
   ...
</authors>

Я предлагаю вам создать файл мета-XML, используя Entity References . Например, вы можете создать следующий XML-файл:

<?xml version="1.0" encoding="UTF-8" ?>
<!ENTITY postfile    SYSTEM "file:///home/username/posts.xml">
<!ENTITY commentfile SYSTEM "file:///home/username/comments.xml">
<!ENTITY authorfile  SYSTEM "file:///home/username/authors.xml">
<root>
  &postfile1;
  &commentfile;
  &authorfile;
</root>

Этот мета-XML-файл (на самом деле, обычный старый XML-файл ... «мета» - это только с точки зрения ваших трех определенных XML-файлов, а не в каком-либо смысле XML) является точным эквивалентом следующего файла и анализаторы XML будут действовать так, как если бы у вас действительно был следующий файл:

<?xml version="1.0" encoding="UTF-8" ?>
<root>
  <posts>
    <post>
      <author name="author1"/>
      <comment id="12345" pos="1"/>
      <comment id="12346" pos="2"/>
      <body>I really like my camera...</body>
    </post>
     ...
  </posts>
  <comments>
    <comment id="12345" author="kindguy">
      That was a very good post
    </comment>
     ...
  </comments>
  <authors>
    <author name="kindguy" id="1"/>
    <author name="author1" id="2"/>
     ...
  </authors>
</root>

Из этого файла вы можете определить схему XML, которая будет применять желаемые ограничения, даже если для отдельных файлов нет способа применить ограничения. Поскольку с помощью нотации сущностей XML вы «включили» весь XML в один файл, вы можете использовать xpath в ссылках на противопоказания.

1 голос
/ 10 января 2012

Этот вопрос обсуждается в http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html примечании, раздел 3.11.

0 голосов
/ 05 марта 2009

Если я правильно помню, xs:ID должен быть глобально уникальным для всего документа, а xs:key должен быть уникальным только для элемента, для которого он был определен. Так что key/keyref на самом деле больше похоже на PK / FK. ПК должны быть уникальными только в одной таблице.

...