對于某些XML模式來說,它是一組嚴格的規則,用于規定XML文檔的結構方式。 但是對于其他人來說,通常的準則是指出XML的外觀。 這意味著有時出于某些原因人們希望接受不符合XML模式的輸入。 在此示例中,我將演示如何利用SAX XMLFilter來完成此操作。
Java模型
下面是將用于此示例的Java模型。
顧客
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批注為模型指定名稱空間限定。
@XmlSchema(namespace='http://www.example.com/customer',elementFormDefault=XmlNsForm.QUALIFIED)
package blog.namespace.sax;import javax.xml.bind.annotation.*;
XML輸入(input.xml)
即使我們的元數據指定所有元素都應使用命名空間(http://www.example.com/customer)限定,我們的輸入文檔也不是使用命名空間限定的。 在解組操作期間,將使用XMLFilter添加名稱空間。
<?xml version='1.0' encoding='UTF-8'?>
<customer><name>Jane Doe</name>
</customer>
XMLFilter(NamespaceFilter)
創建XMLFilter的最簡單方法是擴展XMLFilterImpl 。 對于我們的用例,我們將覆蓋startElement和endElement方法。 在這些方法的每一個中,我們將調用相應的super方法,并將默認名稱空間作為URI參數傳遞。
package blog.namespace.sax;import org.xml.sax.*;
import org.xml.sax.helpers.XMLFilterImpl;public class NamespaceFilter extends XMLFilterImpl {private static final String NAMESPACE = 'http://www.example.com/customer';@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {super.endElement(NAMESPACE, localName, qName);}@Overridepublic void startElement(String uri, String localName, String qName,Attributes atts) throws SAXException {super.startElement(NAMESPACE, localName, qName, atts);}}
演示版
在下面的演示代碼中,我們將對XML文檔進行SAX解析。 XMLReader將包裝在我們的XMLFilter中 。 我們將利用JAXB的UnmarshallerHandler作為ContentHandler 。 解析完成后,我們可以向UnmarshallerHandler請求生成的Customer對象。
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 JAXBContextJAXBContext jc = JAXBContext.newInstance(Customer.class);// Create the XMLFilterXMLFilter filter = new NamespaceFilter();// Set the parent XMLReader on the XMLFilterSAXParserFactory spf = SAXParserFactory.newInstance();SAXParser sp = spf.newSAXParser();XMLReader xr = sp.getXMLReader();filter.setParent(xr);// Set UnmarshallerHandler as ContentHandler on XMLFilterUnmarshaller unmarshaller = jc.createUnmarshaller();UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();filter.setContentHandler(unmarshallerHandler);// Parse the XMLInputSource xml = new InputSource('src/blog/namespace/sax/input.xml');filter.parse(xml);Customer customer = (Customer) unmarshallerHandler.getResult();// Marshal the Customer object back to XMLMarshaller marshaller = jc.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshaller.marshal(customer, System.out);}}
輸出量
以下是運行演示代碼的輸出。 注意輸出如何包含基于元數據的名稱空間限定。
<?xml version='1.0' encoding='UTF-8'?>
<customer xmlns='http://www.example.com/customer'><name>Jane Doe</name>
</customer>
進一步閱讀
如果您喜歡這篇文章,那么您可能也會對以下內容感興趣:
- JAXB和命名空間
- 防止JAXB中的實體擴展攻擊
參考:在Java XML&JSON Binding博客上,我們的JCG合作伙伴 Blaise Doughan 在JAXB Unmarshal期間應用名稱空間 。
翻譯自: https://www.javacodegeeks.com/2012/11/applying-a-namespace-during-jaxb-unmarshal.html