私は私に与えられたxsdファイルに準拠する必要があるいくつかのxmlファイルを生成しています。それらが準拠していることをどのように確認する必要がありますか?
13 に答える
Java ランタイム ライブラリは検証をサポートしています。前回これを確認したのは、隠れている Apache Xerces パーサーでした。おそらくjavax.xml.validation.Validatorを使用する必要があります。
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import java.net.URL;
import org.xml.sax.SAXException;
//import java.io.File; // if you use File
import java.io.IOException;
...
URL schemaFile = new URL("http://host:port/filename.xsd");
// webapp example xsd:
// URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd");
// local file example:
// File schemaFile = new File("/location/to/localfile.xsd"); // etc.
Source xmlFile = new StreamSource(new File("web.xml"));
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
validator.validate(xmlFile);
System.out.println(xmlFile.getSystemId() + " is valid");
} catch (SAXException e) {
System.out.println(xmlFile.getSystemId() + " is NOT valid reason:" + e);
} catch (IOException e) {}
スキーマ ファクトリ定数は、http://www.w3.org/2001/XMLSchema
XSD を定義する文字列です。上記のコードは、URL に対して WAR デプロイメント記述子を検証しますhttp://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
が、ローカル ファイルに対しても同様に簡単に検証できます。
DOMParser を使用してドキュメントを検証するべきではありません (目的がドキュメント オブジェクト モデルを作成することでない限り)。これにより、ドキュメントを解析するときに DOM オブジェクトの作成が開始されます。使用しない場合は無駄です。
Xerces2を使用してそれを行う方法は次のとおりです。このためのチュートリアルはこちら(サインアップが必要)。
元の帰属:ここから露骨にコピー:
import org.apache.xerces.parsers.DOMParser;
import java.io.File;
import org.w3c.dom.Document;
public class SchemaTest {
public static void main (String args[]) {
File docFile = new File("memory.xml");
try {
DOMParser parser = new DOMParser();
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setProperty(
"http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",
"memory.xsd");
ErrorChecker errors = new ErrorChecker();
parser.setErrorHandler(errors);
parser.parse("memory.xml");
} catch (Exception e) {
System.out.print("Problem parsing the file.");
}
}
}
ant を使用してプロジェクトをビルドするので、schemavalidate タスクを使用して構成ファイルを確認できます。
<schemavalidate>
<fileset dir="${configdir}" includes="**/*.xml" />
</schemavalidate>
いたずらな構成ファイルはビルドに失敗します!
これはよくある質問なので、java は「参照先」の xsd に対しても検証できることを指摘します。たとえば、.xml ファイル自体がヘッダーで XSD を指定している場合、xsi:schemaLocation
or xsi:noNamespaceSchemaLocation
(または特定の名前空間の場合は xsi) exを使用します。
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd">
...
または schemaLocation (常に名前空間から xsd へのマッピングのリスト)
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com/my_namespace http://www.example.com/document.xsd">
...
.xsd ファイルは .xml ファイルで宣言された名前空間に "マップ" され、名前空間が宣言されているため、.xml ファイルの名前空間と一致する場合は、他の回答もここで機能します。しかし、カスタムリゾルバーを使用できると便利な場合もあります...
javadocs から: 「URL、ファイル、またはソースを指定せずにスキーマを作成すると、Java 言語は、使用するスキーマを見つけるために検証中のドキュメントを参照するスキーマを作成します。例:」
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
これは複数の名前空間などで機能します。このアプローチの問題は、xmlsns:xsi
おそらくネットワークの場所であるため、デフォルトで出て、すべての検証でネットワークにヒットし、常に最適であるとは限りません。
XML ファイルが参照する XSD に対して検証する例を次に示します (ネットワークからプルする必要がある場合でも)。
public static void verifyValidatesInternalXsd(String filename) throws Exception {
InputStream xmlStream = new new FileInputStream(filename);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(new RaiseOnErrorHandler());
builder.parse(new InputSource(xmlStream));
xmlStream.close();
}
public static class RaiseOnErrorHandler implements ErrorHandler {
public void warning(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
public void error(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
public void fatalError(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
}
xml ファイルが url を参照していても、xsd を手動で指定するか (ここで他の回答を参照)、または「XML カタログ」スタイルのリゾルバーを使用することで、参照された XSD をネットワークからプルすることを回避できます。Spring は、検証のためにローカル ファイルを提供するために URL リクエストをインターセプトすることもできるようです。または、 setResourceResolverを介して独自に設定することもできます。例:
Source xmlFile = new StreamSource(xmlFileLocation);
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setResourceResolver(new LSResourceResolver() {
@Override
public LSInput resolveResource(String type, String namespaceURI,
String publicId, String systemId, String baseURI) {
InputSource is = new InputSource(
getClass().getResourceAsStream(
"some_local_file_in_the_jar.xsd"));
// or lookup by URI, etc...
return new Input(is); // for class Input see
// https://stackoverflow.com/a/2342859/32453
}
});
validator.validate(xmlFile);
別のチュートリアルについては、こちらも参照してください。
デフォルトはDOM解析を使用することだと思います.SAXパーサーでも同様の検証を行うことができます saxReader.setEntityResolver(your_resolver_here);
Java 7 を使用すると、パッケージの説明で提供されるドキュメントに従うことができます。
// create a SchemaFactory capable of understanding WXS schemas SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // load a WXS schema, represented by a Schema instance Source schemaFile = new StreamSource(new File("mySchema.xsd")); Schema schema = factory.newSchema(schemaFile); // create a Validator instance, which can be used to validate an instance document Validator validator = schema.newValidator(); // validate the DOM tree try { validator.validate(new StreamSource(new File("instance.xml")); } catch (SAXException e) { // instance document is invalid! }
もう1つの答え:生成(書き込み)しているファイルを検証する必要があると言ったので、最初に書き込み、次に読み取りを行って検証するのではなく、書き込み中にコンテンツを検証することをお勧めします。SAXベースのライターを使用している場合は、Xml検証用のJDK APIを使用してこれを行うことができます。その場合は、「Validator.validate(source、result)」を呼び出してバリデーターにリンクします。ここで、ソースはライターからのものであり、結果は出力を送信する必要がある場所。
あるいは、コンテンツ(またはstaxを使用する、または使用できるライブラリ)の書き込みにStaxを使用する場合、WoodstoxはXMLStreamWriterを使用する際の検証を直接サポートすることもできます。これがどのように行われるかを示すブログエントリです:
Linux マシンをお持ちの場合は、無料のコマンドライン ツール SAXCount を使用できます。これは非常に便利だと思いました。
SAXCount -f -s -n my.xml
dtd および xsd に対して検証します。50MB のファイルの場合は 5 秒。
Debian スクイーズでは、パッケージ「libxerces-c-samples」にあります。
dtd と xsd の定義は xml にある必要があります。それらを個別に構成することはできません。
プログラムでXMLファイルを生成している場合は、XMLBeansライブラリを確認することをお勧めします。コマンドラインツールを使用して、XMLBeansはXSDに基づいてJavaオブジェクトのセットを自動的に生成してパッケージ化します。次に、これらのオブジェクトを使用して、このスキーマに基づいてXMLドキュメントを作成できます。
スキーマ検証のサポートが組み込まれており、JavaオブジェクトをXMLドキュメントに、またはその逆に変換できます。
XSD に対して XML を検証する必要があったのは 1 回だけだったので、XMLFox を試してみました。とても紛らわしく、奇妙だと思いました。ヘルプの説明がインターフェイスと一致していないようです。
最終的に、LiquidXML Studio 2008 (v6) を使用することになりました。これは、はるかに使いやすく、すぐに慣れることができました (UI は、私が頻繁に使用する Visual Basic 2008 Express に非常に似ています)。欠点: 無料版には検証機能がないため、30 日間の試用版を使用する必要がありました。