XML-схема имеет мощный механизм, называемый «импорт». Импорт позволяет одной XML-схеме ссылаться на элементы и типы из другой XML-схемы. Это означает, что вы можете определить типы для представления часто используемой информации один раз и импортировать эти типы в другие схемы XML. Как и любой мощный инструмент, механизм импорта также обладает способностью причинять боль. В этой статье я покажу, как использовать каталог XML для устранения проблем при использовании инструмента XJC JAXB для генерации классов из схемы XML с импортом.
XML-схемы
Следующие XML-схемы будут использоваться для этого поста. Импортированные схемы ( address.xsd и phone-number .xsd) находятся в подкаталоге с именем « import » относительно customer.xsd .
customer.xsd (корневая XML-схема)
Это корневая XML-схема, из которой мы будем генерировать наши классы Java. Эта XML-схема содержит два оператора импорта:
- Первый импорт включает системный идентификатор, указывающий размещенное местоположение импортированной XML-схемы. Инструмент XJC JAXB может генерировать классы из размещенной схемы XML (см. Обработка каналов Atom с помощью JAXB ), но в этом примере схемы XML все еще находятся в стадии разработки и еще не размещены.
- Второй импорт вообще не включает системный идентификатор. Инструмент XJC не будет знать, где найти импортированную схему XML.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
targetNamespace="http://www.example.com/customer"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.com/customer"
xmlns:add="http://www.example.com/address"
xmlns:phn="http://www.example.com/phone-number"
elementFormDefault="qualified">
<xs:import
schemaLocation="http://www.example.com/address/address.xsd"
namespace="http://www.example.com/address"/>
<xs:import
namespace="http://www.example.com/phone-number"/>
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element ref="add:address"/>
<xs:element ref="phn:phone-number"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/phone-number"
xmlns="http://www.example.com/phone-number"
elementFormDefault="qualified">
<xs:element name="phone-number">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="type" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
XJC — Генерация классов Java из схемы XML
Инструмент XJC можно использовать для генерации классов Java из схемы XML. В этом примере у меня есть customer.xsd в моей локальной файловой системе
xjc -d out customer.xsd
Ниже приведены сообщения об ошибках, которые я получаю при выполнении вышеуказанного вызова XJC. Одна ошибка, которую мы видим, заключается в том, что она не смогла найти схему по адресу «http://www.example.com/address/address.xsd», что, как я уже говорил ранее, ожидается, что я еще не размещал эту XML-схему. Другая ошибка, которую мы видим, заключается в том, что «phn: phone-number» не может быть разрешен в определении элемента, это также ожидается, так как мы не указали расположение схемы.
parsing a schema...
[WARNING] schema_reference.4: Failed to read schema document 'http://www.example.com/address/address.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
line 12 of file:/C:/Program%20Files/Java/jdk1.6.0_20/bin/customer.xsd
[ERROR] src-resolve: Cannot resolve the name 'add:address' to a(n) 'element declaration' component.
line 21 of file:/C:/Program%20Files/Java/jdk1.6.0_20/bin/customer.xsd
[ERROR] src-resolve: Cannot resolve the name 'phn:phone-number' to a(n) 'element declaration' component.
line 23 of file:/C:/Program%20Files/Java/jdk1.6.0_20/bin/customer.xsd
Failed to parse a schema.
Каталог XML (catalog.cat)
Мы можем решить проблемы, с которыми мы сталкиваемся, используя каталог XML. Каталог XML позволит нам указать реальные местоположения для наших импортированных схем XML. Инструмент XJC поддерживает несколько различных форматов каталога XML: TR9401 , XCatalog, каталог OASIS XML .
Форматы каталога XML имеют системные и общедоступные отображения. Системные сопоставления полезны, когда импорт содержит системный идентификатор, а публичные сопоставления должны использоваться, когда импорт не содержит системный идентификатор.
Следующий импорт может использоваться с системным отображением
<xs:import
schemaLocation="http://www.example.com/address/address.xsd"
namespace="http://www.example.com/address"/>
Для этого импорта требуется общедоступное сопоставление на основе URI пространства имен:
<xs:import
namespace="http://www.example.com/phone-number"/>
Ниже приведено несколько примеров, основанных на схемах XML из этого поста:
Формат TR9401
-- Match address.xsd by URL --
SYSTEM "http://www.example.com/address/address.xsd" "imports/address.xsd"
-- Match phone-number.xsd by namespace URI --
PUBLIC "http://www.example.com/phone-number" "imports/phone-number.xsd"
ОАЗИС XML Каталог Формат
<!DOCTYPE catalog
PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN"
"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system
systemId="http://www.example.com/address/address.xsd"
uri="imports/address.xsd"/>
<public
publicId="http://www.example.com/phone-number"
uri="imports/phone-number.xsd"/>
</catalog>
XJC — указание файла каталога
Параметр «-catalog» используется для указания файла каталога при запуске команды XJC для генерации Java, классифицированной из схем XML.
xjc -d out -catalog catalog.cat customer.xsd
От http://blog.bdoughan.com/2011/10/jaxb-xjc-imported-schemas-and-xml.html