Уникальность в XSD или DTD с пространствами имен

Мне нужно создать некоторые правила в .xsd или .dtd для этих случаев:

  1. Название песен не может повторяться. (Я не уверен, сделал ли я это в своем коде, пожалуйста, проверьте)
  2. комментарии к элементам и жанр могут быть необязательными, остальные обязательны. (Я не уверен, сделал ли я это в своем коде, пожалуйста, проверьте)
  3. Всего существует 3 типа значений жанра стихии: поп, рок и джаз. (Я уверен, что сделал это в своем коде, пожалуйста, проверьте)

Это мой код, но я получаю эти ошибки от http://www.xmlvalidation.com/ в XML-документ:

7:  60  Attribute "xmlns" must be declared for element type "catalog".
7:  60  Attribute "xmlns:xsi" must be declared for element type "catalog".
7:  60  Attribute "xsi:schemaLocation" must be declared for element type "catalog".

каталог.XML

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

<!DOCTYPE catalog SYSTEM "catalog.dtd">
<catalog 
xmlns="http://www.w3schools.com" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLoc ation="http://www.w3schools.com catalog.xsd">

<song>
    <name2>Bed of Roses</name2>
    <artist>Bon Jovi</artist>
    <album>Cross Road</album>
    <year>1995</year>
    <genre>rock</genre>
    <comments>Good song</comments>
    <path>C://music/bon jovi</path>
</song>
<song>
    <name2>Fly Away from here</name2>
    <artist>Aerosmith</artist>
    <album>Just Push Play</album>
    <year>2001</year>
    <genre>rock</genre>
    <comments>Good song</comments>
    <path>C://music/aerosmith</path>
</song>
<song>
    <name2>Jossie</name2>
    <artist>Blink 182</artist>
    <album>Blink 182</album>
    <year>2001</year>
    <genre>pop</genre>
    <comments>Good song</comments>
    <path>C://music/blink 182</path>
</song>
<song>
    <name2>Want you bad</name2>
    <artist>The Offspring</artist>
    <album>Conspiracy of One</album>
    <year>2000</year>
    <genre>pop</genre>
    <comments>Good song</comments>
    <path>C://music/the offspring</path>
</song>
<song>
    <name2>The One that you love</name2>
    <artist>Air Supply</artist>
    <album>The One that you love</album>
    <year>1981</year>
    <genre>pop</genre>
    <comments>Good song</comments>
    <path>C://music/air supply</path>
</song>

</catalog>

каталог.DTD

<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT catalog (song+)>
<!ELEMENT song (name2,artist,album,year,genre,comments,path)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT name2 (#PCDATA)>
<!ELEMENT artist (#PCDATA)>
<!ELEMENT album (#PCDATA)>
<!ELEMENT year (#PCDATA)>
<!ELEMENT genre (#PCDATA)>
<!ELEMENT comments (#PCDATA)>
<!ELEMENT path (#PCDATA)>

каталог.XSD

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
 elementFormDefault="qualified">

<xs:element name="catalog">
<xs:complexType>
    <xs:sequence>
        <xs:element name="song" maxOccurs="5">
            <xs:complexType>
                <xs:sequence>
                  <xs:element name="name2" minOccurs="1"type="xs:string"/>
                  <xs:element name="artist" minOccurs="1" type="xs:string"/>
                  <xs:element name="album" minOccurs="1" type="xs:string"/>
                  <xs:element name="year" minOccurs="1" type="xs:integer"/>
                  <xs:element name="genre" minOccurs="0">
                        <xs:simpleType>
                                <xs:restriction base="xs:string">
                                    <xs:enumeration value="pop"/>
                                    <xs:enumeration value="rock"/>
                                    <xs:enumeration value="jazz"/>
                                </xs:restriction>
                        </xs:simpleType>
                  </xs:element>                     
                <xs:element name="comments" minOccurs="0" type="xs:string"/>
                  <xs:element name="path" minOccurs="1" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

person Jose Ricardo Citerio Alcala    schedule 17.03.2015    source источник


Ответы (1)


  1. Название песен не может повторяться. (Я не уверен, сделал ли я это в своем коде, пожалуйста, проверьте)

Да, потому что maxOccurs по умолчанию равно 1. (Значения по умолчанию для minOccurs и maxOccurs равны 1.)

Обновление: чтобы содержимое name2 было уникальным в пределах catalog, используйте xs:unique, как показано в XSD ниже. Затем, если, скажем, есть два элемента name2 с содержимым "Bed of Roses", вы получите сообщение об ошибке, подобное следующему:

[Ошибка].

Следующий вопрос:

  1. элементы comments и genre могут быть необязательными, остальные обязательны. (Я не уверен, сделал ли я это в своем коде, пожалуйста, проверьте)

Да, потому что у comments и genre есть minOccurs="0", а у остальных minOccurs="1".

  1. Есть только 3 типа значений для жанра элемента: поп, рок и джаз. (Я уверен, что сделал это в своем коде, пожалуйста, проверьте)

Правильный.

Теперь об ошибках:

DTD несовместимы с пространствами имен XML без неестественных искажений.

Рекомендую отказаться от DTD и использовать только XSD.

Затем ваш XML без строки DOCTYPE и с небольшой синтаксической правкой (удалить пробел в xsi:schemaLoc ation),

<?xml version="1.0" encoding="UTF-8"?>
<catalog 
    xmlns="http://www.w3schools.com" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.w3schools.com catalog.xsd">

  <song>
    <name2>Bed of Roses</name2>
    <artist>Bon Jovi</artist>
    <album>Cross Road</album>
    <year>1995</year>
    <genre>rock</genre>
    <comments>Good song</comments>
    <path>C://music/bon jovi</path>
  </song>
  <song>
    <name2>Fly Away from here</name2>
    <artist>Aerosmith</artist>
    <album>Just Push Play</album>
    <year>2001</year>
    <genre>rock</genre>
    <comments>Good song</comments>
    <path>C://music/aerosmith</path>
  </song>
  <song>
    <name2>Jossie</name2>
    <artist>Blink 182</artist>
    <album>Blink 182</album>
    <year>2001</year>
    <genre>pop</genre>
    <comments>Good song</comments>
    <path>C://music/blink 182</path>
  </song>
  <song>
    <name2>Want you bad</name2>
    <artist>The Offspring</artist>
    <album>Conspiracy of One</album>
    <year>2000</year>
    <genre>pop</genre>
    <comments>Good song</comments>
    <path>C://music/the offspring</path>
  </song>
  <song>
    <name2>The One that you love</name2>
    <artist>Air Supply</artist>
    <album>The One that you love</album>
    <year>1981</year>
    <genre>pop</genre>
    <comments>Good song</comments>
    <path>C://music/air supply</path>
  </song>

</catalog>

Будет действителен для вашего XSD (опять же, с небольшой синтаксической поправкой: добавьте пробел перед type в объявлении name2):

Обновление: теперь демонстрирует xs:unique для name2:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.w3schools.com"
           xmlns:w3="http://www.w3schools.com"
           elementFormDefault="qualified">

  <xs:element name="catalog">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="song" maxOccurs="5">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="name2" minOccurs="1" type="xs:string"/>
              <xs:element name="artist" minOccurs="1" type="xs:string"/>
              <xs:element name="album" minOccurs="1" type="xs:string"/>
              <xs:element name="year" minOccurs="1" type="xs:integer"/>
              <xs:element name="genre" minOccurs="0">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:enumeration value="pop"/>
                    <xs:enumeration value="rock"/>
                    <xs:enumeration value="jazz"/>
                  </xs:restriction>
                </xs:simpleType>
              </xs:element>                     
              <xs:element name="comments" minOccurs="0" type="xs:string"/>
              <xs:element name="path" minOccurs="1" type="xs:string"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
    <xs:unique name="catalog-song-name2-unique">
      <xs:selector xpath="w3:song"/>
      <xs:field xpath="w3:name2"/>
    </xs:unique>
  </xs:element>
</xs:schema>
person kjhughes    schedule 17.03.2015
comment
Хорошо, приятель, спасибо, я уже удалил .dtd, но я могу использовать одно и то же имя для двух песен, minOccurs = 1 в этом случае не работает, чтобы избежать этого, например, я могу дважды использовать Bed of Roses. - person Jose Ricardo Citerio Alcala; 17.03.2015
comment
О, я думал, вас интересует только кардинальность элемента name2. Чтобы значение name2 не повторялось, используйте xs:unique. Я обновил XSD в ответе, чтобы показать вам, как это сделать. - person kjhughes; 17.03.2015
comment
эй, приятель, я получаю эту ошибку в .xsd на www.xmlvalidation.com: 32: 39 c-general-xpath-ns: префикс пространства имен в выражении XPath «w3: песня» не был привязан к пространству имен. - person Jose Ricardo Citerio Alcala; 17.03.2015
comment
Уверяю вас, что XML, включенный в этот ответ, успешно сверяется с XSD в этом ответе. Я подтвердил это как в автономном режиме через Xerces-J, так и в Интернете на сайте www.xmlvalidation.com, на котором, к сожалению, отсутствуют средства связи, чтобы я мог просто показать вам. Предложите вам еще раз проверить, что вы загрузили XML и XSD из ответа, а не из вопроса. Спасибо. - person kjhughes; 17.03.2015
comment
Блин, приятель, ты прав. ты чертовски классный, спасибо за твою помощь. - person Jose Ricardo Citerio Alcala; 17.03.2015