2015-03-10 4 views
1

Мне нужно создать правило dtd, чтобы не повторять значения элемента XML, в этом случае у меня есть каталог, содержащий 5 песен (имя, исполнитель, альбом, ...), а значения элемента имени не могут Повторюсь, что не может быть две песни с таким же названием, мой код здесь:Как создать правило dtd для этого XML?

XML 

<?xml version="1.0"?> 
<!DOCTYPE catalog SYSTEM "catalog.dtd"> 
<catalog> 
    <song> 
    <name>Bed of Roses</name> 
    <artist>Bon Jovi</artist> 
    <album>Cross Road</album> 
    <year>1995</year> 
    <genre>Ballad</genre> 
    <coments>Good song</coments> 
    <path></path> 
</song> 
<song> 
    <name>Fly Away from here</name> 
    <artist>Aerosmith</artist> 
    <album>Just Push Play</album> 
    <year>2001</year> 
    <genre>Rock</genre> 
    <coments>Good song</coments> 
    <path></path> 
</song> 
</catalog> 

DTD 
<?xml version="1.0"?> 
<!ELEMENT catalog (song)> 
<!ELEMENT song (name,artist,album,year,genre,comments,path)> 
<!ELEMENT song (name)> 
<!ELEMENT name (#PCDATA)> 
<!ELEMENT artist (#PCDATA)> 
<!ELEMENT album (#PCDATA)> 
<!ELEMENT year (#PCDATA)> 
<!ELEMENT genre (#PCDATA)> 
<!ELEMENT comments (#PCDATA)> 
+1

Это невозможно. DTD не могут выразить требуемое ограничение (обеспечивая уникальные значения для определенных элементов). Вам придется использовать некоторые другие технологии, например [Schematron] (http://en.wikipedia.org/wiki/Schematron). – mzjn

+0

Мой Учитель в Интернете просит меня сделать это –

+0

@mzjn - Это технически возможно (см. Уродливый хак ниже), но я согласен, что есть лучшие технологии для обеспечения такого ограничения. –

ответ

2

Что вы могли сделать, это использовать уникальный идентификатор на name элемента. Это только дает вам половину пути; идентификатор должен быть уникальным, но он не ограничивает PCDATA в name.

Чтобы обойти это, создайте текстовые объекты, чтобы удерживать элементы имени. Вы можете ссылаться только на объект один раз. Если вы ссылаетесь на него более одного раза, вы получите ошибку, аналогичную:

Значение атрибута «song1» идентификатора типа должно быть уникальным в документе.

Это гарантирует, что имя будет использоваться только один раз.

Вот пример. (Кроме того, было несколько опечаток, которые сделали ваш XML/DTD недействителен Те были исправлены.).

catalog.dtd

<!ELEMENT catalog (song+)> 
<!ELEMENT song (name,artist,album,year,genre,comments,path)> 
<!ELEMENT name (#PCDATA)> 
<!ATTLIST name 
      id ID #REQUIRED> 
<!ELEMENT artist (#PCDATA)> 
<!ELEMENT album (#PCDATA)> 
<!ELEMENT year (#PCDATA)> 
<!ELEMENT genre (#PCDATA)> 
<!ELEMENT comments (#PCDATA)> 
<!ELEMENT path (#PCDATA)> 

<!ENTITY song1 '<name id="song1">Bed of Roses</name>'> 
<!ENTITY song2 '<name id="song2">Fly Away from here</name>'> 

XML

<!DOCTYPE catalog SYSTEM "catalog.dtd"> 
<catalog> 
    <song> 
     &song1; 
     <artist>Bon Jovi</artist> 
     <album>Cross Road</album> 
     <year>1995</year> 
     <genre>Ballad</genre> 
     <comments>Good song</comments> 
     <path></path> 
    </song> 
    <song> 
     &song2; 
     <artist>Aerosmith</artist> 
     <album>Just Push Play</album> 
     <year>2001</year> 
     <genre>Rock</genre> 
     <comments>Good song</comments> 
     <path></path> 
    </song> 
</catalog> 

Отказ от ответственности: Я думаю, это уродливый взлом лично. Как и mzjn, в комментариях есть другие технологии, более подходящие для обеспечения такого ограничения.

+0

Использование уникальности идентификаторов работает, но это не ограничивает содержание элемента. «Bed of Roses» как название обеих песен не приводит к ошибке. Уродливая ручка. Но творческий. Стоит перемирие. – mzjn

Смежные вопросы