ファイルに書き込む前に、メモリ内の xml ドキュメントを検証しようとしています。私の問題に似た質問がたくさん見つかりましたが、ここには違いがあると思います。この検証用に複数のスキーマが定義されており、次のように親から子への関係で「再定義」オプションが使用されます: CoreSchema.xsd -> CenterSchema.xsd -> CenterSchema_REF.xsd
CoreSchema.xsd (セキュリティ ポリシーのため、完全ではなくサンプルです)
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://www.example.com/supplier" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/supplier" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.8">
<xs:element name="NewIssue">
<xs:annotation>
<xs:documentation>Root element to add new issues</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="NewIssueList">
<xs:annotation>
<xs:documentation>Contains a list of issues</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="Issue" type="ImportIssueType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
...
...
CenterSchema.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://www.example.com/supplier" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://http://www.example.com/supplier" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.8">
<xs:redefine schemaLocation="CoreSchema.xsd">
<xs:complexType name="Issue">
<xs:complexContent>
<xs:extension base="Issue">
<xs:sequence>
<xs:element name="Component" type="Components"/>
<xs:element name="Keywords" type="Keywords" minOccurs="0"/>
<xs:element name="SupplierStatus" type="SupplierStatus" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ImportIssueType">
<xs:annotation>
<xs:documentation>Definition of a exported issue</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="ImportIssueType">
<xs:sequence>
<xs:element name="Component" type="Components">
<xs:annotation>
<xs:documentation>Describes the component where the issue occurs.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Keywords" type="Keywords" minOccurs="0">
<xs:annotation>
<xs:documentation>Keyword applied for the issue.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
...
...
</xs:redefine>
</xs:schema>
CenterSchema_REF.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://www.example.com/supplier" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/supplier" elementFormDefault="qualified" attributeFormDefault="unqualified" version="4.7">
<xs:redefine schemaLocation="CenterSchema.xsd">
...
...
</xs:redefine>
編集済み:シリアル化されたドキュメント (.xml ファイルに記述) は次のようになります。
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<NewIssue xmlns="http://www.example.com/supplier" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/supplier CenterSchema_REF.xsd">
<NewIssueList>
<Issue>
<SupplierID>574</SupplierID>
<NewIssueMode>Read Only</NewIssueMode>
<Author>
<Name/>
</Author>
<Category>Software</Category>
<ItemType>Test-Issue</ItemType>
<IssueClass>Issue</IssueClass>
<DetectedOnDate>2014-08-14</DetectedOnDate>
<Device>TEST</Device>
<Severity>1</Severity>
<Supplier>
<ContactName/>
<Data>Analysis: [Reason of problem] [Condition for defect] [Impact] [Risk] [Root cause]</Data>
<Status>Supplier Not Assigned</Status>
<StatusInternal>SUBMITTED</StatusInternal>
</Supplier>
...
...
</Issue>
</NewIssueList>
</NewIssue>
次のように SchemaFactory と検証を実装しました。
private boolean toFile(final String outputPath, final Node document) {
boolean resultOk = false;
try {
DOMSource domSource = new DOMSource(document);
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
factory.setResourceResolver(new CustomResourceResolver());
try {
InputStream schemaCSREF = DxiParser.class.getResourceAsStream("/CenterSchema_REF.xsd");
factory.setFeature("http://apache.org/xml/features/honour-all-schemaLocations", true);
factory.setFeature("http://apache.org/xml/features/validation/schema-full-checking", false);
Source source = new StreamSource(schemaCSREF);
Schema schema = factory.newSchema(source);
Validator validator = schema.newValidator();
validator.validate(domSource);
} catch (SAXException e) {
// instance document is invalid!
System.out.println(e.getLocalizedMessage());
System.out.println("\n** SAX Parser: Error during validation of " +document.getNodeName());
return false;
}
FileOutputStream xmlOut = new FileOutputStream(new File(outputPath));
StreamResult streamResult = new StreamResult(xmlOut);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
// serializer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,"users.dtd");
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.transform(domSource, streamResult);
xmlOut.close();
resultOk = true;
// ---- Error handling ----
} catch (TransformerConfigurationException tce) {
System.out.println("\n** Transformer Factory error");
System.out.println(" " + tce.getMessage());
Throwable e = (tce.getException() != null) ? tce.getException()
: tce;
e.printStackTrace();
} catch (TransformerException tfe) {
System.out.println("\n** Transformation error");
System.out.println(" " + tfe.getMessage());
Throwable e = (tfe.getException() != null) ? tfe.getException()
: tfe;
e.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
return resultOk;
}
CustomResourceResolver は次のように実装されます。
public class CustomResourceResolver implements LSResourceResolver {
@Override
public LSInput resolveResource(String type, String namespaceURI,
String publicId, String systemId, String baseURI) {
LSInputImpl input = new LSInputImpl();
InputStream stream = null;
try {
stream = new FileInputStream(new File(systemId));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
input.setPublicId(publicId);
input.setSystemId(systemId);
input.setBaseURI(baseURI);
input.setCharacterStream(new InputStreamReader(stream));
return input;
}
}
LSInput の実装は標準です。
public class LSInputImpl implements LSInput{
private Reader characterStream;
private InputStream byteStream;
private String stringData;
private String systemId;
private String publicId;
private String baseURI;
private String encoding;
private boolean certifiedText;
//getters and setters
}
すべてのスキーマ ファイルがロードされ (パスで見つかります)、スキーマ オブジェクトに取り込まれていることを確認できます。Schema オブジェクトの Grammar フィールドを見ると、すべての複合型が検出され、XSComplexTypeDecl の配列に次の特定のエントリが読み込まれていることがわかります。
複合型名=' http://www.example.com/supplier,#AnonType_NewIssue ', 基本型名='anyType', コンテンツ型='ELEMENT', isAbstract='false', hasTypeId='false', final= '0'、block='0'、particle='(" http://www.example.com/supplier ":NewIssueList)'、derivedBy='RESTRICTION'.
これは、CenterSchema_REF を介して到達した CenterSchema を介して CoreSchema に到達したことの証拠です。注: 工場出荷時の機能 " http://apache.org/xml/features/validation/schema-full-checking " を true に設定すると、XSComplexTypeDecl フィールドが null になります。
3 つすべての xsds を Source[] として追加しようとしましたが、エラーは同じです。さまざまなファクトリ機能を true/false に設定して実験してみました。
他に何を確認すればよいかわかりません。完全に立ち往生しています。
必要があれば、さらに情報を追加できます。皆さんありがとう。