Я использую сторонний веб-сервис, определение которого и реализация находятся вне моего контроля. Этот веб-сервис изменится в будущем.
Веб-сервис должен использоваться для генерации XML-файла, который содержит некоторые из тех же данных (представленный теми же типами XSD) как веб-сервис плюс некоторая дополнительная информация, сгенерированная программой.
Мой подход:
XSD вводит, я собираюсь использовать в своем собственном файле XSD, но определяюсь в WSDL, подвержены изменениям. Каждый раз, когда они изменяются, я хотел бы автоматически обработать XSD и WSDL, связывающий с данными снова. (Если изменение является достаточно существенным, это могло бы инициировать некоторое усилие по разработке. (Но обычно нет.))
Моя проблема:
На шаге 1 мне нужен XSD, относящийся к тем же типам, как используется веб-сервисом.
WSDL относится к другому WSDL, который относится к другому WSDL и т.д. В конечном счете существует WSDL с необходимыми встроенными типами XSD. Насколько я знаю, что нет никакого способа непосредственно сослаться на встроенные типы XSD WSDL от XSD.
Подход я думал бы самый жизнеспособный, должен включать дополнительный шаг в автоматическую обработку (перед привязкой данных), который извлекает встроенный XSD из WSDL в другой файл (файлы) XSD. Эти другой файл (файлы) XSD может затем быть упомянут моим собственным файлом XSD.
Вещи я хотел бы избежать:
PS: Я нашел некоторые подобные вопросы, но у них всех были ответы как: WTH Вы хотели бы сделать это? Это - причина моей довольно большой фоновой истории.
Я не знаю библиотек, которые могли бы сделать это за вас, но это определенно возможно реализовать, приложив немного усилий (~200 строк). Грубая мета-программа для генерации всех встроенных и включенных XSD:
method processWSDL(Document wsdl) {
for each ("/wsdl:definitions/wsdl:types/xsd:schema" in wsdl) {
call processXSD("inline_[i].xsd",".")
}
for each ("/wsdl:definitions/wsdl:import" in wsdl) {
Document x = read and parse ("@location")
if (x is WSDL) call processWSDL(x)
else if (x is XSD) call processXSD("@location", x)
}
}
method processXSD(String filename, Document xsd) {
write "xsd" to a new file "filename" // if 'filename' is a URL, take only the part after the last '/'
for each ("/xsd:schema/xsd:import" or "/xsd:schema/xsd:include" in xsd) {
if ("@schemaLocation" is local reference) { // no 'http://' prefix
Document x = read and parse ("@schemaLocation")
call processXSD("@schemaLocation", x)
}
}
}
Это не полное решение, например, не обрабатывает префиксы пространств имен, определенные вне встроенной схемы, но, надеюсь, дает хорошую отправную точку.