2016-02-16 3 views
0

У меня есть много внешних DTD для разных типов документов XML. Все DTD очень похожи: включают общие определения DTD, а затем 5-10 строк определений типа документа, которые полагаются на общие определения. Хотя конкретные определения коротки, общие определения велики.объединить несколько DTD в одну или повторно использовать общую часть

Возможно ли каким-либо образом объединить все эти небольшие внешние DTD в один большой DTD?

Конкретная проблема, которую я испытываю, это накладные расходы на разбор DTD. Первой идеей было кэширование разобранных DTD. И все же идея потерпела неудачу, поскольку, как я выяснил, каждый из DTD (с libxml2 v2.9.2) занимает ~ 1,1 МБ ОЗУ: умножается на ~ 25, количество DTD, что намного выше нашего предела памяти , Поскольку 99% DTD на самом деле являются одними и теми же общими определениями, я ищу способы как-то повторно использовать общую часть.

ответ

0

(Ответ на себя.)

Можно ли каким-то образом объединить все эти небольшие внешние DTDs в один большой DTD?

Это похоже невозможно. Я не нашел никаких официальных средств для этого.

Возможно, что libxml2 не предоставляет какие-либо нестандартные возможности для этого.

Я ищу способы как-то повторно использовать общую часть.

Анализ проблемы в глубину, с помощью libxml2, я нашел 2 возможности.

  1. Оптимизируйте DTD. После загрузки DTD расширения/объекты расширяются, а DTD становится плоским списком под-узлов (элементов, сущностей, атрибутов и т. Д.), Закрепленных на узле DTD. Начиная с узла верхнего уровня (соответствующего DOCTYPE), можно получить список суб-узлов DTD, которые фактически используются (+), и удалить все, что не используется. Затем, используя функцию демпинга, один раз можно записать оставшиеся записи в новый DTD-файл, который теперь должен быть намного меньше оригинала. ((+) Хотя глубокая интроспекция под-узлов DTD, похоже, не поддерживается, все равно можно извлечь информацию из строкового представления узла.)

  2. Динамически составлять DTD в памяти из общих и определений типа документа. Просмотрев API libxml2, я нашел функцию, которая позволяет расширить анализируемый DTD в памяти: xmlAddElementDecl() и xmlAddAttributeDecl(). API кажется рудиментарным. Но, по крайней мере, представляется возможным: загрузить общую часть; загрузить конкретную деталь типа документа; временно, с помощью функций, перемещать (или копировать) суб-узлы от более позднего к первому. После перемещения структура DTD в памяти должна быть почти идентична структуре DTD исходного DTD. Позже, после того, как была выполнена валидация, можно вернуться (или освободить копии) узлов, чтобы снова (снова) использовать большую (большую) часть.

К сожалению, на данный момент у меня не было времени проверить ни один из подходов на практике.