无法验证具有多个 XSD 架构的 XML 位置

  • 本文关键字:XML 位置 XSD 验证 java xml
  • 更新时间 :
  • 英文 :


我尝试验证包含多个XSD的XML,验证是可以的,但不应该如此。

例如,我的 XML 是

<cnt:FirstXsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cat="CommonTypes"
xmlns:cnt="FirstXsd"
xmlns:env="http://www.w3.org/2001/06/soap-envelope"
xsi:schemaLocation="FirstXsd FirstXsd.xsd">
<cat:DocumentID>TEST_TEXT</cat:DocumentID>
<cnt:FirstDoc>
<cnt:DocBody>
<sec:SecondXsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cat="CommonTypes"
xmlns:sec="SecondXsd"
xsi:schemaLocation="SecondXsd Second.xsd">
<cat:DocumentID>TEST_NUMBER</cat:DocumentID>    
</sec:SecondXsd>
</cnt:DocBody>
</cnt:FirstDoc>
</cnt:FirstXsd>

并且需要<cat:DocumentID>TEST_NUMBER</cat:DocumentID>

我用那个代码检查

public class Main {
public static void main(String[] args) {
File xsds=new File[]{new File(this.getClass().getClassLoader().getResource("First.xsd").getFile()),new File(this.getClass().getClassLoader().getResource("Second.xsd").getFile())};
File xml = new File(this.getClass().getClassLoader().getResource("test.xml").getFile());
System.out.println(validation.validateXMLByXSD_Array(new StreamSource(new StringReader(xml)),xsds));
}

public boolean validateXMLByXSD_Array(Source xml, File[] xsds) {
Source[] sources = new Source[xsds.length];
for (int i = 0; i < xsds.length; i++) {
sources[i] = new StreamSource(xsds[i]);
}
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
Schema schema = schemaFactory.newSchema(sources);
Validator validator = schema.newValidator();
validator.setErrorHandler(new ForgivingErrorHandler());
validator.validate(xml);
}  catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}

所以,我的问题是每次我都没有收到任何错误,如果我是否删除重新查询的<cat:DocumentID>。但是,如果我删除 First.xsd 所需的完整<cnt:DocBody>,则会出现错误。

似乎只有XML中JVM中出现的第一个XSD正在检查。当我尝试调试时,我看到我的架构内部有两个 xsd,就像写在这里一样

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:cat="CommonTypes:1.0" xmlns:cnt="FirstXsd:1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="FirstXsd:1.0" elementFormDefault="qualified" version="1.0">
<xs:import namespace="CommonTypes:1.0" schemaLocation="CommonTypes.xsd"/>
<xs:element name="FirstXsd" type="cnt:FirstXsdType"/>
<xs:complexType name="FirstXsdType">
<xs:complexContent>
<xs:extension base="cat:BaseDocType">
<xs:attribute name="DocumentModeID" type="cat:DocumentModeIDType" use="required" fixed="TEST_TEXT"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="ContainerDocType">
<xs:sequence>
<xs:element name="Element1" type="cat:Element1" minOccurs="0"/>
<xs:element name="Element2" type="cat:Element2" minOccurs="0"/>
<xs:element name="Element3" type="cat:Element3" minOccurs="0"/>
<xs:element name="DocBody" type="cat:DocBodyType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="DocBodyType">
<xs:sequence>
<xs:any processContents="skip"/>
</xs:sequence>
</xs:complexType>
</xs:schema>

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cat="CommonTypes:1.0" xmlns:sec="SecondXsd:1.0" targetNamespace="SecondXsd:1.0" elementFormDefault="qualified" version="1.0">
<xs:import namespace="CommonTypes:1.0" schemaLocation="CommonTypes.xsd"/>
<xs:element name="SecondXsd" type="sec:SecondXsdType"/>
<xs:complexType name="SecondXsdType">
<xs:complexContent>
<xs:extension base="cat:BaseDocType">
<xs:sequence>
<xs:element name="Element1" type="cat:Element1"/>
<xs:element name="Element2" type="cat:Element2"/>
<xs:element name="Element3" type="cat:Element3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

感谢您提供 xsds。查看 CommonTypes.xsd 的定义也很有用。但是,我想我可以根据您发布的内容发表有用的评论。

您声称 cat:DocumentID 是必需的,但它没有出现在 cnt:FirstXsd 内容的任何地方。CommonTypes.xsd 是否定义了名为"DocumentID"的全局元素?即使有,你的XSD也不会引用它,所以它不需要作为cnt:FirstXsd的成员。

我不认为这是XSD验证的Java实现中的缺陷。请解释您要实现的目标,以便我们提出更好的解决方案。

最新更新