3

これを読んだ後、RelaxNG XMLバリデーター(Jing)で使用されるカスタムデータ型を実装しようとしています。Jing(彼らはそれを呼んでいますdatatype-sample)によって提供されたサンプル実装をコマンドラインで正常に実行しましたが、Javaコードから実行することに失敗し続けています。

コマンドライン(Windows)から:

> 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>

そして、2番目の引数は次の内容のファイルへのパスです。

<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)は、私が知る限り満たされています。だから私は何が間違っているのですか?

PS:上記のコードを機能させるにはjing.jardatatype-sample.jarクラスパスに引数を指定し、最初のコードがパスdatatype-sample.rngで、2番目のコードがパスvalid.xmlまたはである引数を指定する必要がありますinvalid.xml。これらはすべてJingとともに配布されます。

Edit1:java -jar上記のプログラムは、適切なファイルを使用してJAR()として実行した場合、IDEの外部でも機能しませんMANIFEST.MF。クラスパスが手動で設定されている場合も機能しません(java -classpath)。したがって、実際のコードに何か問題があるのではないかと思います。

4

2 に答える 2

3

JAXPAPIを介してJingを介してカスタムデータ型ライブラリを使用することはどういうわけか壊れているようです。動作するはずなのに動作しません。おそらく、いくつかの追加のプロパティをどこかに設定する必要がありますが、私はこれに気づいていません。

com.thaiopensource.relaxng.util.Driverしたがって、Jingを模倣し、Jing独自のAPIを使用して検証を実行することで回避策を見つけたと思います。そうすることでコードが制限されるため、Jingでのみ機能することに注意してください。

package rngdatatype;

import com.thaiopensource.validate.SchemaReader;
import com.thaiopensource.validate.ValidationDriver;
import com.thaiopensource.validate.auto.AutoSchemaReader;
import java.io.File;
import java.io.IOException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class JingApi {

    public static void main(String[] args) throws SAXException, IOException {
        String rng = args[0];
        String xml = args[1];
        File rngFile = new File(rng);
        File xmlFile = new File(xml);

        SchemaReader sr = new AutoSchemaReader();
        ValidationDriver driver = new ValidationDriver(sr);
        InputSource inRng = ValidationDriver.fileInputSource(rngFile);
        inRng.setEncoding("UTF-8");
        driver.loadSchema(inRng);
        InputSource inXml = ValidationDriver.fileInputSource(xmlFile);
        inXml.setEncoding("UTF-8");
        driver.validate(inXml);
    }
}

これにより、カスタムデータ型ライブラリを使用するRNGスキーマに基づいてJavaコードからXMLファイルを検証できます。Diver前述のクラスは直接使用できないことに注意してください。

上記のプログラムは、私自身の質問の例と同じクラスパスと引数を使用しています。

編集1---------------------------------------------

もう少しいじった後、カスタムデータ型ライブラリを使用するときにJAXPの例をJingと一緒に再生するために設定する必要のあるプロパティを見つけました。次のインスタンスを取得した後、次の行を追加するだけですSchemaFactory

rngSchemaFactory.setProperty("http://relaxng.org/properties/datatype-library-factory", new org.relaxng.datatype.helpers.DatatypeLibraryLoader());

これは、JingネイティブAPIを使用するよりもはるかに洗練されたソリューションです。

/ Edit1 --------------------------------------------

于 2012-06-08T09:22:56.247 に答える
0

JARファイルには、ファイルMETA-INF / services / org.relaxng.datatype.DatatypeLibraryFactoryの形式で追加のメタデータが含まれている必要があります。このファイルには、インターフェースorg.relaxng.datatype.DatatypeLibraryFactoryを実装するクラスの名前が含まれている必要があります。

于 2012-06-01T08:17:57.660 に答える