【问题标题】:XML is not validated with the XSD using XAS parser未使用 XAS 解析器通过 XSD 验证 XML
【发布时间】:2014-07-03 13:39:15
【问题描述】:

我下面的xml好像验证不成功。

addressbook.xml

<?xml version ="1.0" encoding="UTF-8"?>

<addressbook>
    <address>
        <name>
            <first-name>Samitha</first-name>
            <last-name>Chathuranga</last-name>
            <sasa>dd</sasa>
        </name>
        <street>107 B</street>
        <village>Poramba</village>
        <city>AG</city>
        <postal-code>80300</postal-code>
        <country>Sri Lanka</country>
    </address>
    <address>
        <name>
            <first-name>Hasara</first-name>
            <last-name>Semini</last-name>
        </name>
        <street>32 A</street>
        <village>Dombanwila</village>
        <city>RG</city>
        <postal-code>34300</postal-code>
        <country>Sri Lanka</country>
    </address>

</addressbook>

我已经添加了额外的元素 dd 来检查它是否已验证到以下 XSD,但似乎没有。没有错误消息出现。所以验证似乎不成功。

addressbook.xsd

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="addressbook">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="address" maxOccurs="unbounded"/>          
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="address" >
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="name" />
                <xsd:element ref="street" />
                <xsd:element ref="village" />
                <xsd:element ref="city" />
                <xsd:element ref="postal-code" />
                <xsd:element ref="country" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="name">
        <xsd:complexType>
        <xsd:sequence>
            <xsd:element ref="first-name"/>
            <xsd:element ref="last-name"/>
        </xsd:sequence>
    </xsd:complexType>
    </xsd:element>
    <xsd:element name="first-name" type="xsd:string" />
    <xsd:element name="last-name" type="xsd:string" />
    <xsd:element name="street" type="xsd:string" />
    <xsd:element name="village" type="xsd:string" />

    <xsd:element name="city">
        <xsd:simpleType>
            <xsd:restriction base="xsd:string">
                <xsd:length value="2" />
            </xsd:restriction>
        </xsd:simpleType>
    </xsd:element>

    <xsd:element name="postal-code" type="xsd:string" />
    <xsd:element name="country" type="xsd:string" />

</xsd:schema>

这是什么原因?

以下是用于使用 SAX 进行验证和解析的 2 个 java 类。

SAX_XSDValidator.java

//1. Checks for well-formed-ness of the XML with extrnal XML Schema when parsing by SAX Parser.
//2. Validated the XML file with external XML schema Using SAX Parser

// JAXP
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

public class SAX_XSDValidator {
    public static void main(String[] args) {
        try {

            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            XMLReader reader = parser.getXMLReader();
            // checking for well-formed-ness using SAX.=>This doesn't validate
            // against XSD
            // Turn off validation, and turn on namespaces
            factory.setValidating(false);
            factory.setNamespaceAware(true);
            reader.setErrorHandler(new SimpleErrorHandler());
            reader.parse(new InputSource("src/addressbook.xml"));
            System.out.println("Checked well-formed-ness using SAX ");


            // validating using external schema Using SAX Parser
            // SAXParserFactory factory = SAXParserFactory.newInstance();
            factory.setValidating(true);
            factory.setNamespaceAware(true);
            SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
            factory.setSchema(schemaFactory.newSchema(new Source[] { new StreamSource("src/addressbook.xsd") }));
            reader.setErrorHandler(new SimpleErrorHandler());
            reader.parse(new InputSource("src/addressbook.xml"));
            System.out.println("Validation Checked when Parsing with SAX");


            System.out.println("Parsing successful");

        } catch (ParserConfigurationException e) {
            System.out.println("The underlying parser does not support "
                    + " the requested features.");
        } catch (FactoryConfigurationError e) {
            System.out.println("Error occurred obtaining SAX Parser Factory.");
        } catch (Exception e) {
            System.out.println("Caught Exception");
            e.printStackTrace();
        }
    }
}

SimpleErrorHandler.java

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ErrorHandler;

public class SimpleErrorHandler implements ErrorHandler {
    public void warning(SAXParseException e) throws SAXException {
        System.out.println(e.getMessage());
    }

    public void error(SAXParseException e) throws SAXException {
        System.out.println(e.getMessage());
    }

    public void fatalError(SAXParseException e) throws SAXException {
        System.out.println(e.getMessage());
    }

}

【问题讨论】:

    标签: java xml validation xsd sax


    【解决方案1】:

    您需要创建一个新的 SAXParser :您正在更改 factory 变量,但您的 reader 仍然使用旧的 SAXParser

    // checking for well-formed-ness using SAX.
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setValidating(true);
    factory.setNamespaceAware(true);
    
    SAXParser parser = factory.newSAXParser();
    XMLReader reader = parser.getXMLReader();
    
    reader.setErrorHandler(new SimpleErrorHandler());
    reader.parse(new InputSource("src/addressbook.xml"));
    System.out.println("Checked well-formed-ness using SAX ");
    
    
    // validating using external schema Using SAX Parser
    factory.setValidating(false); // set validation to false
    SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
    factory.setSchema(schemaFactory.newSchema(new Source[] { new StreamSource("src/addressbook.xsd") }));
    
    parser = factory.newSAXParser(); // create a new parser
    reader = parser.getXMLReader(); // and refresh your reader
    
    reader.setErrorHandler(new SimpleErrorHandler());
    reader.parse(new InputSource("src/addressbook.xml"));
    System.out.println("Validation Checked when Parsing with SAX");
    
    
    System.out.println("Parsing successful");
    

    【讨论】:

    • 非常感谢。问题被它解决了。但我有一个问题.. 为什么要设置 factory.setValidating(false)。实际上,将其设置为真或假会发生什么?当我在上面将其设置为 true 时,出现错误,因为“文档无效:找不到语法。文档根元素“地址簿”,必须匹配 DOCTYPE 根“null”。由于没有引用 DOCTYPE,文档怎么会无效?
    • setValidating() 将通过查找 DTD(一种语法)来验证您的 XML。但是在这里,您使用的是 XSD,而不是 DTD,那么您必须禁用此验证。 “真正的”验证是由setSchema() 函数带来的。 (source)
    • 但我还有另一个问题。在第一部分“//使用 SAX 检查格式正确。=>当我在上面给出 setValidating(true) 时,这不会针对 XSD 进行验证” ""文档无效:未找到语法。文档根元素“地址簿”,必须匹配 DOCTYPE 根“null”。没有错误。实际上根本没有错误。所以它与你上面的解释相当矛盾..!!!
    • 只要不设置Schema,SAX就不会检查有效性。
    • 你没有正确回答我的问题。我的问题是,即使我在第一部分中给出了 setValidating(true),上述错误不会出现?我还没有确定DTD。所以根据你之前的解释,因为我没有给出DTD,应该会出现错误..这里是什么情况......?
    猜你喜欢
    • 2015-01-01
    • 1970-01-01
    • 2013-08-30
    • 1970-01-01
    • 2015-06-28
    • 2018-08-08
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    相关资源
    最近更新 更多