![](/img/trans.png)
[英]JAXP: How to validate a org.w3c.dom.Document against a XML Schema
[英]How to validate an XML document using a RELAX NG schema and JAXP?
我想使用RELAX NG schemata驗證XML文檔,我想使用JAXP驗證API 。
從谷歌搜索,似乎我可以使用Jing和ISO RELAX JARV到JAXP Bridge 。 不幸的是,在將兩者都添加到我的類路徑后,我無法讓它工作。 SchemaFactory
只是在嘗試實例化一個工廠時拋出一個IllegalArgumentException
- 我在SchemaFactory
查看,顯然SchemaFactoryFinder
返回一個null結果。
所以我很欣賞這兩個問題的答案:
我需要這個來使用Java 5和Java 6。
謝謝!
我使用以下行解決了Java 1.6上的這個錯誤:
// Specify you want a factory for RELAX NG "compact"
System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, "com.thaiopensource.relaxng.jaxp.CompactSyntaxSchemaFactory");
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI);
這允許我使用Jing來針對Compact RELAX NG模式驗證XML文檔。 完整的例子如下。 我沒有使用這座橋或其他任何東西。 運行時類路徑只有jing.jar(20091111)和我自己的Validator類。
import java.io.File;
import java.io.IOException;
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 Validate
{
public static void main(String[] args) throws SAXException, IOException
{
// Specify you want a factory for RELAX NG
System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, "com.thaiopensource.relaxng.jaxp.CompactSyntaxSchemaFactory");
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI);
// Load the specific schema you want.
// Here I load it from a java.io.File, but we could also use a
// java.net.URL or a javax.xml.transform.Source
File schemaLocation = new File(args[0]);
// Compile the schema.
Schema schema = factory.newSchema(schemaLocation);
// Get a validator from the schema.
Validator validator = schema.newValidator();
for (int i = 1; i < args.length; i++)
{
String file = args[i];
// Check the document
try
{
validator.validate(new StreamSource(new File(file)));
System.out.println(file + " is valid.");
}
catch (SAXException ex)
{
System.out.print(file + " is not valid because: " + ex.getMessage());
}
}
}
}
再一次,我只測試了這個離子Java 1.6。
$ java -version
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)
請參閱2008年3月7日撰寫的Stefan Bodewig的Weblog,標題為XMLUnit中的RELAX NG驗證 :
從昨晚開始,XMLUnit的trunk包含一個新的Validator類,它基於javax.xml.validation,它是JAXP 1.3(即Java5 +)的一部分。
...
據我所知,沒有JAXP實現支持RELAX NG開箱即用。 Sun自己的JAXP 1.4(Java6 +)肯定沒有。 一些搜索帶我到Kohsuke Kawaguchi的博客誰應該知道,因為他的工作在JAXP,Sun的多架構驗證器,isorelax和其他東西。
使用他的isorelax-bridge和Jing並沒有讓我在Java6上的任何地方。 我回到了Kohsuke Kawaguchi的文章並閱讀了評論:由於他們改變了SchemaFactory查找算法,因此橋不能與Java6一起使用。 好了,嘗試了Java5 - 進步,我現在在Jing內部的某個地方得到一個NullPointerException,所以至少它正在加載工廠。 接下來我用MSV取代了Jing(現在就在這里 ,不管有多少鏈接引導你到Sun的WebServices堆棧頁面,以及“好的URL永遠不會改變”),真的,我的簡單測試通過了。
所以你可能不得不跳過一些環節來獲得RELAX NG支持到你的JAXP設置 - 在我的例子中,Java5,MSV和Kawaguchi的橋工作,但是評論表明它應該也適用於Java6 - 但是一旦你設法配置一切正確地說,XMLUnit現在可以讓你在單元測試中斷言文檔的有效性。 但它似乎不適用於緊湊語法。
要閱讀關於Kohsuke Kawaguchi博客的評論,你必須使用archive.org,因為他們現在都不見了:
Java 5將服務提供者文件解釋為鍵/值對的列表,這違反了Java 5和6 JAR文件規范,但恰好與您的示例相匹配。
Java 6按指定解析服務提供者文件,即。 作為完全限定類名的列表,但因此無法實例化適配器的SchemaFactory,因為服務提供者文件的內容無效。
要與Java 5和Java 6兼容而不必更改JAXP-JARV適配器JAR文件,可以簡單地添加另一個包含正確的javax.xml.validation.SchemaFactory服務提供程序文件的JAR文件。
另一個選項是Trang ,它是一個RelaxNG-to-XMLSchema翻譯器。 我相信它被設計用作構建工具而不是運行時庫,但您最好的選擇可能是在構建時使用Trang將模式轉換為XMLSchema,然后對其進行驗證。 這樣,您可以准確地看到翻譯的樣子,同時充分利用JAXP的XML Schema支持。
... 一旦嘗試實例化工廠,就會出現IllegalArgumentException
意味着模式語言無法識別,可能有幾個原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.