XSD 或带有命名空间的 DTD 中的唯一性

Uniqueness in XSD or DTD with namespaces

我需要在 .xsd 或 .dtd 中为这些情况创建一些规则:

  1. 歌曲名称不能重复。 (我不确定我是否做到了 在我的代码中,请检查)
  2. 元素评论和流派可以是 可选的,其余的都是必需的。 (我不确定我是否做到了 在我的代码中,请检查)
  3. 只有 3 种类型的值 元素流派,流行,摇滚和爵士乐。 (我确信我在我的代码中做到了, 请检查)

这是我的代码,但我从 XML 文档中的 http://www.xmlvalidation.com/ 得到了这个错误:

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".

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>

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)>

catalog.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>
  1. The name of the songs cant be repeated. (I am not sure if I did it in my code, please check)

是的,因为 maxOccurs 默认为 1。 (minOccursmaxOccurs 的默认值为 1。)

Update:要强制 name2 的内容在 catalog 中是唯一的,请使用 xs:unique,如 XSD 下面。然后,如果有两个 name2 元素包含 "Bed of Roses" 内容,您将收到如下错误:

[Error] catalog.xml:17:32: cvc-identity-constraint.4.1: Duplicate unique value [Bed of Roses] declared for identity constraint "catalog-song-name2-unique" of element "catalog".

下一题:

  1. the elements comments and genre can be optional, the rest of them are required. (I am not sure if I did it in my code, please check)

是的,因为commentsgenreminOccurs="0",其余有minOccurs="1"

  1. There are just 3 types of values for the element genre, pop, rock and jazz.(I am sure I did it in my code, please check)

正确。

现在,关于错误:

DTD 与 XML 名称不兼容,space 没有不自然的扭曲。

建议您放弃 DTD,只使用 XSD。

然后,您的 XML 没有 DOCTYPE 行并进行了较小的语法更正(删除 xsi:schemaLoc ation 中的 space),

<?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 有效(同样,稍作语法更正:在 name2 的声明中的 type 之前添加 space:

更新: 现在为 name2 演示 xs:unique

<?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>