如何使用xsd架构和SAX验证xml?

时间:2012-05-28 20:11:31

标签: xsd-validation

我将用xml描述我的问题。

首先我用命名空间定义了我的xsd模式,它看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"           targetNamespace="http://www.example.org/schema"
xmlns:tns="http://www.example.org/schema" elementFormDefault="qualified">

<element name="Clients" type="tns:ClientsType"></element>


<complexType name="ContactType">
    <sequence>
        <element name="Type" type="string"></element>
    </sequence>
    <attribute name="ID" type="long" />
</complexType>


<complexType name="Contact">
    <sequence>
        <element name="ContactType" type="tns:ContactType"></element>
        <element name="Value" type="string"></element>
    </sequence>
    <attribute name="ID" type="long" />
</complexType>

<complexType name="ContactsType">
    <sequence>
        <element name="Contact" type="tns:Contact" maxOccurs="unbounded"></element>
    </sequence>

</complexType>


<complexType name="ClientType">
    <sequence>
        <element name="FirstName" type="string"></element>
        <element name="SecondName" type="string"></element>
        <element name="Contacts" type="tns:ContactsType"></element>
    </sequence>
    <attribute name="ID" type="long" />
</complexType>


<complexType name="ClientsType">
    <sequence>
        <element name="Client" type="tns:ClientType" maxOccurs="unbounded"></element>
    </sequence>
</complexType>

所以它产生了明显的xml,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<tns:Clients xmlns:tns="http://www.example.org/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/schema schema.xsd ">
<tns:Client ID="0">
    <tns:FirstName>tns:FirstName</tns:FirstName>
    <tns:SecondName>tns:SecondName</tns:SecondName>
    <tns:Contacts>
        <tns:Contact ID="0">
            <tns:ContactType ID="0">
                <tns:Type>tns:Type</tns:Type>
            </tns:ContactType>
            <tns:Value>tns:Value</tns:Value>
        </tns:Contact>
    </tns:Contacts>
</tns:Client>

我的函数用数据创建特定的xml:

            @Override
        public void printToFile() throws IOException, XMLStreamException {

        FileWriter fd = new FileWriter(outPath);
        Random rand = new Random();
        int end = rand.nextInt(1000);
        try{
        XMLOutputFactory xof = XMLOutputFactory.newInstance();
        XMLStreamWriter xtw = null;

    xtw = xof.createXMLStreamWriter(fd);


    xtw.writeStartDocument();

    //xtw.setPrefix("tns", "http://www.example.org/schema");
        xtw.writeStartElement("Clients");
        xtw.writeNamespace("tns", "http://www.example.org/schema");

     xtw.writeStartElement("tns","Client", "http://www.example.org/schema");
          //xtw.writeStartElement("Client");
            xtw.writeAttribute("ID", "1");
            xtw.writeStartElement("FirstName");
                xtw.writeCharacters("NameFirst");
            xtw.writeEndElement();
            xtw.writeStartElement("SecondName");
                xtw.writeCharacters("NameSecond");
            xtw.writeEndElement();
            xtw.writeStartElement("Contacts");
             for(int i=1;i<2;i++){
                    xtw.writeStartElement("Contact");
                        xtw.writeAttribute("ID",Integer.toString(i));
                        xtw.writeStartElement("ContactType");
                            xtw.writeAttribute("ID", Integer.toString(i));
                            xtw.writeStartElement("Type");
                                xtw.writeCharacters("mojTyp");
                            xtw.writeEndElement();                      
                        xtw.writeEndElement();
                            xtw.writeStartElement("Value");
                                xtw.writeCharacters("value");
                            xtw.writeEndElement();
                    xtw.writeEndElement();
             }

            xtw.writeEndElement();


        //xtw.writeEndElement();
        xtw.writeEndDocument();



    }catch(XMLStreamException xmlE)
    {

    }
    finally
    {
        fd.close();
    }

}

我生成简单的Junit测试usinx Sax来验证我的函数创建的xml:

@Test
public void testPrintToFileGoodXml() throws IOException,
        XMLStreamException, FactoryConfigurationError, SAXException {
    mService.printToFile();
    XMLStreamReader reader = XMLInputFactory.newInstance()
            .createXMLStreamReader(new FileInputStream(myPath));
    SchemaFactory factory = SchemaFactory
            .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

    Schema schema = factory.newSchema(new File(mySchemaPath));
    Validator validator = schema.newValidator();

    validator.validate(new StAXSource(reader));
    assertTrue(true);
}

但测试失败所以我认为我的printToFile函数与命名空间和xsd架构中定义的其他属性相关联存在问题,我不知道如何解决它。我读了许多网站和定义xsd的文档,我仍然不知道如何解决我的问题。请帮忙。

1 个答案:

答案 0 :(得分:1)

架构说根元素应该是客户端

Graphical representation of schema

但是,您的XML代码段有一个开放元素tns:Clients,但没有coreponsing关闭元素。检查你的writeEndElement调用是否正确。

<?xml version="1.0" encoding="UTF-8"?>
<tns:Clients xmlns:tns="http://www.example.org/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/schema Contacts.xsd ">
    <tns:Client ID="0">
        <tns:FirstName>tns:FirstName</tns:FirstName>
        <tns:SecondName>tns:SecondName</tns:SecondName>
        <tns:Contacts>
            <tns:Contact ID="0">
                <tns:ContactType ID="0">
                    <tns:Type>tns:Type</tns:Type>
                </tns:ContactType>
                <tns:Value>tns:Value</tns:Value>
            </tns:Contact>
        </tns:Contacts>
    </tns:Client>
</tns:Clients> <--------- Missing