Проверка XML: нет соответствующего глобального объявления, доступного для корня проверки

Я пытаюсь проверить следующий XML против схемы XSD с помощью Ruby. Он просто не будет работать, останавливается с сообщением об ошибке, сообщающим мне

Error: Element 'request': нет соответствующего глобального объявления, доступного для корня проверки.

может быть, это пространство имен? Есть идеи?

XML

<?xml version="1.0" encoding="UTF-8"?>
<request type="test" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <channel name="channel">
    <username>user</username>
    <password>pass</password>
  </channel>

  <hotel id="1">
    <date from="2009-07-07" to="2009-07-17"/>
    <room id="1">
      <allocation>10</allocation>
    </room>
  </hotel>
</request>   

xsd-схемы

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <!-- channel -->
  <xsd:element name="channel">
    <xsd:attribute name="name" use="required" type="xsd:string" />
    <xsd:sequence>
      <xsd:element username="name" use="required" type="xsd:string"/>
      <xsd:element password="country" use="required" type="xsd:string"/>
    </xsd:sequence>
  </xsd:element>

  <!-- hotel -->
  <xsd:element name="hotel">
    <xsd:attribute name="id" use="required" type="xsd:string" />
    <xsd:sequence>
      <xsd:element name="hotel">
        <xsd:attribute name="from" use="required" type="xsd:string" />
        <xsd:attribute name="to" use="required" type="xsd:string" />
      </xsd:element>
      <xsd:element ref="room" minOccurs="1"/>
    </xsd:sequence>
  </xsd:element>


  <!-- room -->
  <xsd:element name="room">
    <xsd:sequence>
      <xsd:element name="allocation" type="xsd:string"></xsd:element>
      <xsd:element ref="hotel" minOccurs="1"/>
    </xsd:sequence>
    <xsd:attribute name="id" use="required" type="xsd:string" />
  </xsd:element>

  <!-- building all together -->
  <xsd:element name="request">
    <xsd:attribute name="type" use="required" type="xsd:string" />
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="channel" maxOccurs="1"/>
        <xsd:element ref="hotel" maxOccurs="1"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Руби код

require "xml"

document = LibXML::XML::Document.file("/tmp/test.xml")
schema = LibXML::XML::Document.file("/tmp/request.xsd")

result = document.validate_schema(schema) do |message,flag|
  log.debug(message)
  puts message
end

3 ответов


это загадочная ошибка, но это, вероятно, потому, что ваш XSD искажен. Например, содержание канала, гостиницы (как внутренних, так и внешних элементов), номера и запроса xsd:element теги должны быть обернуты в xsd:complexType теги. Кроме того,use действует только на xsd:attribute, а не xsd:element. Для элементов используйте minOccurs и maxOccurs (хотя по умолчанию они равны 1, поэтому в этом случае они не нужны). Кроме того, ваш внешний элемент hotel содержит элемент room, который должен содержит элемент hotel, создавая бесконечный цикл. Кроме того, вы неправильно называете свои элементы имени пользователя и пароля. Наконец, этот внутренний элемент отеля, вероятно, должен быть свиданием. Вот что я думаю, что вы ищете:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <!-- channel -->
  <xsd:element name="channel">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="username" type="xsd:string"/>
        <xsd:element name="password" type="xsd:string"/>
      </xsd:sequence>
      <xsd:attribute name="name" use="required" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>

  <!-- hotel -->
  <xsd:element name="hotel">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="date">
          <xsd:complexType>
            <xsd:attribute name="from" use="required" type="xsd:string" />
            <xsd:attribute name="to" use="required" type="xsd:string" />
          </xsd:complexType>
        </xsd:element>
        <xsd:element ref="room" minOccurs="1"/>
      </xsd:sequence>
      <xsd:attribute name="id" use="required" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>


  <!-- room -->
  <xsd:element name="room">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="allocation" type="xsd:string"></xsd:element>
      </xsd:sequence>
      <xsd:attribute name="id" use="required" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>

  <!-- building all together -->
  <xsd:element name="request">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="channel" maxOccurs="1"/>
        <xsd:element ref="hotel" maxOccurs="1"/>
      </xsd:sequence>
    <xsd:attribute name="type" use="required" type="xsd:string" />
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

просто стрельба из бедра здесь, но вы пытались преобразовать XML:: документ, содержащий схему в XML:: Schema?

http://libxml.rubyforge.org/rdoc/classes/LibXML/XML/Schema.html

Я не знаю, что это будет иметь значение, но это стоит попробовать.


я получил то же самое загадочное сообщение об ошибке по другой причине.

первая строка моего файла схемы имела незафиксированное пространство имен:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.sec.gov/edgar/document/thirteenf/informationtable" xmlns:ns1="http://www.sec.gov/edgar/common" targetNamespace="http://www.sec.gov/edgar/document/thirteenf/informationtable" elementFormDefault="qualified" attributeFormDefault="unqualified">

обратите внимание на атрибут' xmlns='. Это поместило все элементы, объявленные в схеме, в пространство имен http://www.sec.gov/edgar/document/thirteenf/informationtable (если не указано иное с префиксом пространства имен). Но XML-файл, который я пытался проверить, не имеет соответствующего без префиксов/пространство имен по умолчанию:

<informationTable xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

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