Прочитав это, я попытался реализовать пользовательский тип данных для использоваться валидатором XML RelaxNG (Jing). Я успешно запустил пример реализации, предоставленный Jing (они называют его datatype-sample
) через командную строку, но мне не удается сделать это из java-кода.
Из командной строки (окна):
> set CLASSPATH=path\to\jing-20091111\bin\jing.jar;path\to\jing-20091111\sample\datatype\datatype-sample.jar
> cd path\to\jing-20091111\sample\datatype
> java com.thaiopensource.relaxng.util.Driver datatype-sample.rng valid.xml
Проверка прошла без проблем. Но теперь я пытаюсь использовать ту же библиотеку типов данных из следующего кода Java:
package rngdatatype;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.xml.sax.SAXException;
public class Main {
public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException, SAXException, IOException {
// make sure our jars are on classpath
System.out.println("Classpath: " + System.getProperty("java.class.path"));
// args
String rng = args[0];
String xml = args[1];
File rngFile = new File(rng);
File xmlFile = new File(xml);
// setup rng validator through JAXP
System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, "com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory");
SchemaFactory rngSchemaFactory = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI);
// obtain a schema object
InputStreamReader rngReader = new InputStreamReader(new FileInputStream(rngFile), "UTF-8");
Schema schema = rngSchemaFactory.newSchema(new StreamSource(rngReader));
// validate using schema based validator
Validator validator = schema.newValidator();
InputStreamReader xmlReader = new InputStreamReader(new FileInputStream(xmlFile), "UTF-8");
validator.validate(new StreamSource(xmlReader));
}
}
Первый аргумент — это путь к файлу со следующим содержимым:
<element name="balancedString"
xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.thaiopensource.com/relaxng/datatypes/sample">
<data type="balancedString"/>
</element>
И вторым аргументом является путь к файлу со следующим содержимым:
<balancedString>foo(bar(baz))</balancedString>
Что дает мне следующий вывод:
Classpath: path\to\RNGDataType\lib\datatype-sample.jar;path\to\RNGDataType\lib\jing.jar;path\to\RNGDataType\build\classes;path\to\RNGDataType\src
Exception in thread "main" org.xml.sax.SAXParseException: datatype library "http://www.thaiopensource.com/relaxng/datatypes/sample" not recognized
...
Это ясно указывает на то, что тип данных не может быть разрешен. Насколько я могу судить, единственное требование для этого (иметь как jing.jar
, так и datatype-sample.jar
в пути к классам) выполнено. Так что я делаю неправильно?
P.S: чтобы приведенный выше код работал, вы должны поместить jing.jar
и datatype-sample.jar
в свой путь к классам И предоставить ему аргументы, где первый - это путь к datatype-sample.rng
, а второй - путь к valid.xml
или invalid.xml
. Все они распространяются вместе с Jing. .
Edit1: указанная выше программа также не работает за пределами моей IDE при запуске в виде JAR (java -jar
) с правильным файлом MANIFEST.MF
. Также не работает, если путь к классам задан вручную (java -classpath
). Поэтому я подозреваю, что что-то не так с фактическим кодом.