好的,所以这就是我想要实现的目标。我正在开发一个小型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网上论坛中,但没有人提出想法。
注意:我使用了此示例中的上述代码:How to validate an XML document using a RELAX NG schema and JAXP?
我怀疑App Engine由于某种原因没有加载Jing.jar。我不知道怎么能检查它是不是。
任何帮助将不胜感激!谢谢!
答案 0 :(得分:3)
这篇文章只是为了澄清。
我用Jing和Relax NG验证XML文档的常用方法是:
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交换。
答案 1 :(得分:0)
我猜是System.setProperty()
失败了,或者说没有正确使用。根据{{3}}:
所有系统属性和环境变量都是您的应用程序专用的。设置系统属性只会影响应用程序对该属性的视图,而不会影响JVM的视图。
如果SchemaFactory是JDK的一部分(我认为它是),您可能无法重置它。但是,您可能更有幸在the docs中设置系统属性,因为这可能会在启动顺序的早期更改。
答案 2 :(得分:0)
好吧,我实际上找到了一种完全取消使用System.setProperty(几乎是hackish)的各种解决方法。
事实证明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);
像魅力一样工作。