XML - статьи

Использование возможностей абстрактных отношений Infoset


В первую очередь необходимо обнаружить все объявления complexType в схеме, поскольку они являются единственным местом, где действительно могут использоваться атрибуты. Необязательно искать все объявления атрибутов, так как позже всегда можно посмотреть в каждом complexType, какие атрибуты в нем используются. Обращение с запросом к схеме - очень простой процесс: пройдитесь по содержанию и отыщите сложные типы. Заметьте, что для изучения содержания схемы имеется множество методов формирования запросов, и это только один из них.



Листинг 1. Обнаружение complexType

// Find type definitions: for our purposes, the simplest // way to get all complexTypes is to drop down to the // underlying EMF model of a schema to iterate through // all concrete components contained within this schema // (Поиск определения типа: в нашем примере самый простой // способ получить все complexTypes опуститься к // базовой EMF-модели схемы, чтобы пройтись по всем // конкретным компонентам, находящимся в ней) List complexTypeDefinitions = new ArrayList(); for (Iterator iter = schema.eAllContents(); iter.hasNext(); ) { XSDConcreteComponent concreteComponent = (XSDConcreteComponent)iter.next(); if (concreteComponent instanceof XSDComplexTypeDefinition) { complexTypeDefinitions.add(concreteComponent); } } // An alternate method would be to use the abstract Infoset // relationship of schema.getTypeDefinitions(), which would // get all globally-visible typedefs (simple and complex) // within the whole schema, however that would miss any // types that were nested inside of other components // (Альтернативный способ - воспользоваться абстрактным // Infoset-отношением schema.getTypeDefinitions(), который // нашел все глобально видимые определения типов (простых и сложных) // во всей схеме, но тогда все вложенные в другие компоненты типы // остались бы незамеченными)

Теперь, когда у нас есть список всех complexType, которые необходимо скорректировать, давайте исключим любые типы, которые несовместимы с рассматриваемой программой. Поскольку мы просто запрашиваем информацию о различных компонентах схемы, можно воспользоваться многими абстрактными отношениями Infoset и методами, которые предлагает Модель. Эти абстрактные методы автоматически учитывают такие понятия, как базовые и производные типы, ссылки на объявления, находящиеся где-нибудь в другом месте, а также действие импортированных, включенных или переопределенных документов схемы.




Листинг 2. Поиск случаев несовместимости

// Detect name collisions between top-level elems and attrs // ( Обнаруживает конфликт имен между высокоуровневыми // элементами и атрибутами) List elementNames = getElementNames(complexType); List attributeNames = getAttributeNames(complexType); attributeNames.retainAll(elementNames); if (!attributeNames.isEmpty()) { // Report the name collision and return... // (Сообщает о конфликте имен и возвращает...) }

// Now check for any attribute wildcards, which we // can't really change into elements // (Проверяет групповые символы, которые нельзя // превратить в элементы) XSDWildcard attributeWildcard = complexType.getAttributeWildcard(); if (null != attributeWildcard) { // Report an incompatible wildcard and return... // (Сообщает о несовместимых групповых символах имен и возвращает...) }

// Check the content for other incompatible conditions like // groups with choice or all or a simpleType // (Проверяет содержание на другие несовместимые условия, как // группы с выбором или все или simpleType) XSDComplexTypeContent complexTypeContent = complexType.getContent(); if (complexTypeContent instanceof XSDSimpleTypeDefinition) { // Report a simple type as incompatible and return... // (Сообщает о несовместимых простых типах и возвращает...) } else if (null != complexTypeContent) { XSDTerm particleTerm = ((XSDParticle)complexTypeContent).getTerm();

if (particleTerm instanceof XSDModelGroup) { XSDCompositor compositor = ((XSDModelGroup)particleTerm).getCompositor(); if ((XSDCompositor.ALL_LITERAL == compositor) (XSDCompositor.CHOICE_LITERAL == compositor)) { // Report an incompatible group type and return... // (Сообщает о несовместимых типах групп и возвращает...) } } // more checks for wildcards, etc. // (еще проверки групповых символов и т.д.) }

Примечание. В этом примере приведен не весь код, используемый для обнаружения случаев несовместимости; пожалуйста, скачайте zip-файл с примерами (см. ), чтобы увидеть его целиком. Программа MakeSoapCompatible.java тщательно спроектирована, в ней приводятся подробные комментарии, указывающие, как манипулировать схемами с помощью этой Модели. Их изучение является необходимым условием, если вы хотите углубиться свои знания.


Содержание раздела