Java Can';t使用多个XSD模式位置验证XML

Java Can';t使用多个XSD模式位置验证XML,java,xml,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/

我尝试用几个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>

测试文本
测试编号
并且需要
测试编号

我用那个密码检查

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;
}
公共类主{
公共静态void main(字符串[]args){
文件xsds=new File[]{新文件(this.getClass().getClassLoader().getResource(“First.xsd”).getFile()),新文件(this.getClass().getClassLoader().getResource(“Second.xsd”).getFile())};
File xml=新文件(this.getClass().getClassLoader().getResource(“test.xml”).getFile());
System.out.println(validation.validateXMLByXSD_数组(新的StreamSource(新的StringReader(xml)),xsds));
}
公共布尔validateXMLByXSD_数组(源xml,文件[]xsds){
Source[]sources=新源[xsds.length];
for(int i=0;i
所以,我的问题是,如果我删除requeired
或不删除requeired
,每次都没有错误。但是,如果我删除First.xsd中所需的完整
,我会得到错误

似乎只有XML中出现的第一个XSD是检查的



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

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


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

您需要共享两个XSD文件。可能最好将它们都减少到该场景所需的最低定义。@kimbert,这不是问题。看起来有些问题这个问题在Java中,因为,如果我不在Java代码中选择SecondXsd,我不会得到任何异常,但如果我不选择FirstXsd,我会得到两个异常,因为两个XSD中都没有每个元素。在创建XSD时,我可能会犯错误,但主要问题不在DocumentID中n当
validator
开始验证具有复杂结构的XML时,它定义我的第一个XSD,检查它,甚至不检查内部的第二个XSD复杂类型。当我填充每个必填字段时,验证器说一切正常。但如果我将第二个XSD的所有字段留空(在第一个和第二个xsdx中,大约有50个字段)无论如何,一切都没问题。但是,如果我不将FirstXsd添加到
文件XSD
中,我会得到关于FirstXsd和SecondXsd的错误,比如
SAXParseException;cvc elt.1:找不到元素“cnt:FirstXsd”的声明。例如,我认为您不理解XSD验证是如何工作的。这使得解释您所做的工作非常困难做错了(特别是当你没有真正说出你想做的事情时)。我可以建议你回到基础上来吗?创建一些非常简单的XSD并使用它们,直到你了解事情是如何工作的。然后回到这个问题上来-即使你不能解决它,你也可以更清楚地解释问题。这是一个很好的建议,转到基础上来,但我可以理解。如果我用 validator
在Java中,当XML没有任何必填字段时,我会遇到任何错误,与FirstXsd的情况相同。我发现了问题所在。问题出在。正因为如此,Java不会验证SecondXsd。因此。您可以放弃您的答案并使用该结论创建新的。否则,您关于基础知识的建议会帮助我)
<?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>