Проверка XML: для корня проверки не найдено подходящего глобального объявления. - PullRequest
8 голосов
/ 17 июня 2009

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

Ошибка: элемент '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 ]

10 голосов
/ 17 июня 2009

Это загадочная ошибка, но, вероятно, потому, что ваш 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>
2 голосов
/ 17 июня 2009

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

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

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

1 голос
/ 12 февраля 2015

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

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

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

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

...