Для некоторых 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 .