Использование Jing с Google App Engine. Не удается загрузить SchemaFactory из-за схемы Relax NG
Итак, вот кратко о том, чего я пытаюсь достичь. Я разрабатываю небольшое приложение Google App Engine, которое генерирует XML для конкретного объекта.
Теперь я столкнулся с проблемами, потому что мне нужно использовать схему Relax NG и проверить ее по моему объекту Document. Это отлично работает на моей локальной машине (Eclipse Helios Java EE, Mac OS X Snow Leopard, Google Web Toolkit 2.2.0, App Engine 1.4.2), но, как только я внедряюсь в App Engine, мой код завершается ошибкой и выдает исключение IllegalArgumentException,
Конкретное исключение заключается в следующем:
java.lang.IllegalArgumentException: No SchemaFactory that implements the schema language specified by: http://relaxng.org/ns/structure/1.0 could be loaded
Конкретные строки кода, на которые он жалуется, следующие:
System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, "com.thaiopensource.relaxng.jaxp.CompactSyntaxSchemaFactory");
SchemaFactory schemaFac = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI);
Последняя строка - это строка, которая выдает исключение.
Я пытался искать в Интернете и опубликовал в нескольких группах Google, но никто не выдвинул идею.
Примечание: я использовал часть приведенного выше кода из этого примера: Как проверить XML-документ, используя схему RELAX NG и JAXP?
Я подозреваю, что App Engine по какой-то причине не загружает Jing.jar. Я не знаю, как я могу проверить, что это / не так.
Любая помощь будет оценена! Спасибо!
3 ответа
Ну, я на самом деле нашел обходной путь, который полностью исключает (практически хакерское) использование System.setProperty.
Оказывается, у Jing есть небольшой класс, который называется "CompactSyntaxSchemaFactory".
Вот как я это использовал:
DocumentBuilderFactory docFactory = null;
CompactSyntaxSchemaFactory scReader = new CompactSyntaxSchemaFactory();
URL relaxSchemaURL = new URL("http://example.com/myschema.rng");
Schema2 relaxSchema = scReader.newSchema(relaxSchemaURL);
docFactory = DocumentBuilderFactory.newInstance();
docFactory.setSchema(relaxSchema);
Работал как шарм.
Этот пост просто для уточнения.
Обычный способ проверки документа XML с помощью Jing и Relax NG:
System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, "com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory");
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI);
Schema schema = factory.newSchema(new File("path/to/schema.rng"));
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new StringReader(xmlString)));
Теперь в App Engine первые две строки не работают и вызывают выброс IllegalArgumentException, как вы сказали. Так что обмениваю их
SchemaFactory factory = new XMLSyntaxSchemaFactory();
делает трюк. Резюме (включая импорт):
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory;
SchemaFactory factory = new XMLSyntaxSchemaFactory();
Schema schema = factory.newSchema(new File("path/to/schema.rng"));
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new StringReader(xmlString)));
Обратите внимание, что это для схем в синтаксисе XML. Для компактного синтаксиса замените XMLSyntaxSchemaFactory на CompactSyntaxSchemaFactory.
Я предполагаю, что System.setProperty()
сбой, или, скорее, не используется правильно. Согласно документам:
Все системные свойства и переменные среды являются частными для вашего приложения. Установка системного свойства влияет только на представление этого свойства вашим приложением, а не на представление JVM.
Если SchemaFactory является частью JDK (что, я думаю, так и есть), вы не сможете сбросить ее. Однако вам, возможно, повезет больше, установив системное свойство в файле appconfig, так как это может измениться ранее в последовательности запуска.