Для некоторых XML-схема — это строгий набор правил для структурирования XML-документа. Но для других это общее руководство, чтобы указать, как должен выглядеть XML. Это означает, что иногда люди хотят принять ввод, который по какой-то причине не соответствует схеме XML. В этом примере я продемонстрирую, как это можно сделать, используя SAX XMLFilter .
Модель Java
Ниже приведена модель Java, которая будет использоваться для этого примера.
Клиент
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
 | 
package blog.namespace.sax;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElementpublic class Customer {    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }} | 
Пакет-инфо
Мы будем использовать аннотацию уровня пакета @XmlSchema, чтобы указать квалификацию пространства имен для нашей модели.
| 
 1 
2 
3 
4 
5 
6 
 | 
@XmlSchema(        elementFormDefault=XmlNsForm.QUALIFIED)package blog.namespace.sax;import javax.xml.bind.annotation.*; | 
XML Input (input.xml)
Несмотря на то, что в наших метаданных указано, что для всех элементов должно быть определено пространство имен (http://www.example.com/customer), наш входной документ не квалифицирован для пространства имен. XMLFilter будет использоваться для добавления пространства имен во время операции unmarshal .
| 
 1 
2 
3 
4 
 | 
<?xml version='1.0' encoding='UTF-8'?><customer>    <name>Jane Doe</name></customer> | 
XMLFilter (NamespaceFilter)
Самый простой способ создать XMLFilter — это расширить XMLFilterImpl . Для нашего варианта использования мы переопределим методы startElement и endElement . В каждом из этих методов мы будем вызывать соответствующий супер-метод, передавая пространство имен по умолчанию в качестве параметра URI.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
 | 
package blog.namespace.sax;import org.xml.sax.*;import org.xml.sax.helpers.XMLFilterImpl;public class NamespaceFilter extends XMLFilterImpl {    @Override    public void endElement(String uri, String localName, String qName)            throws SAXException {        super.endElement(NAMESPACE, localName, qName);    }    @Override    public void startElement(String uri, String localName, String qName,            Attributes atts) throws SAXException {        super.startElement(NAMESPACE, localName, qName, atts);    }} | 
демонстрация
В демонстрационном коде ниже мы сделаем SAX-анализ XML-документа. XMLReader будет помещен в наш XMLFilter . Мы будем использовать UnmarshallerHandler от JAXB в качестве ContentHandler . После завершения анализа мы можем запросить UnmarshallerHandler для полученного объекта Customer .
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
 | 
package blog.namespace.sax;import javax.xml.bind.*;import javax.xml.parsers.*;import org.xml.sax.*;public class Demo {    public static void main(String[] args) throws Exception {        // Create the JAXBContext        JAXBContext jc = JAXBContext.newInstance(Customer.class);        // Create the XMLFilter        XMLFilter filter = new NamespaceFilter();        // Set the parent XMLReader on the XMLFilter        SAXParserFactory spf = SAXParserFactory.newInstance();        SAXParser sp = spf.newSAXParser();        XMLReader xr = sp.getXMLReader();        filter.setParent(xr);        // Set UnmarshallerHandler as ContentHandler on XMLFilter        Unmarshaller unmarshaller = jc.createUnmarshaller();        UnmarshallerHandler unmarshallerHandler = unmarshaller                .getUnmarshallerHandler();        filter.setContentHandler(unmarshallerHandler);        // Parse the XML        InputSource xml = new InputSource('src/blog/namespace/sax/input.xml');        filter.parse(xml);        Customer customer = (Customer) unmarshallerHandler.getResult();        // Marshal the Customer object back to XML        Marshaller marshaller = jc.createMarshaller();        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);        marshaller.marshal(customer, System.out);    }} | 
Выход
Ниже приведен результат запуска демонстрационного кода. Обратите внимание, что выходные данные содержат квалификацию пространства имен на основе метаданных.
| 
 1 
2 
3 
4 
 | 
<?xml version='1.0' encoding='UTF-8'?>    <name>Jane Doe</name></customer> | 
Дальнейшее чтение
Если вам понравился этот пост, то вы также можете быть заинтересованы в:
Ссылка: применение пространства имен во время JAXB Unmarshal от нашего партнера по JCG Блэза Дафана в блоге Java XML & JSON Binding .