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