jaxb讀取xml時忽略命名空間解決讀取時報錯問題

在xml時一般我們會加上xsd等約束和命名空間,加上了有時會導致jaxb讀取xml報錯,衆裏尋他千百度,那人卻在燈火闌珊處,經過一番苦尋找到了解決方法,忽略命名空間的方式讀取xml,實例代碼如下:

package xxx;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.sax.SAXSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLFilterImpl;
import org.xml.sax.helpers.XMLReaderFactory;

public class XmlOperator {

 /**
     * 讀取XML-可配置忽略命名空間
     * 
     * @param file XML文件
     * @param type 類型
     * @param <T> 數據類型
     * @param ignoreNamespace 解析時是否忽略命名空間
     * @return 數據對象
     * @author chang.xu
     */
    @SuppressWarnings("unchecked")
    public <T> T readXml(final File file, final Class<T> type, final boolean ignoreNamespace) {
        T objResult = null;
        FileInputStream fis = null;
        try {
            JAXBContext context = JAXBContext.newInstance(type);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            
            XMLReader reader = XMLReaderFactory.createXMLReader();
            XMLFilterImpl nsfFilter = new XMLFilterImpl() {
                
                @Override
                public void startDocument() throws SAXException {
                    super.startDocument();
                }
                
                @Override
                public void startElement(String uri, String localName, String qName, Attributes atts)
                    throws SAXException {
                    String strURI = uri;
                    if (ignoreNamespace) {
                        strURI = "";
                    }
                    super.startElement(strURI, localName, qName, atts);
                }
                
                @Override
                public void endElement(String uri, String localName, String qName) throws SAXException {
                    String strURI = uri;
                    if (ignoreNamespace) {
                        strURI = "";
                    }
                    super.endElement(strURI, localName, localName);
                }
                
                @Override
                public void startPrefixMapping(String prefix, String url) throws SAXException {
                    super.startPrefixMapping(prefix, url);
                }
            };
            fis = new FileInputStream(file);
            nsfFilter.setParent(reader);
            InputSource input = new InputSource(fis);
            SAXSource source = new SAXSource(nsfFilter, input);
            objResult = (T) unmarshaller.unmarshal(source);
        } catch (JAXBException | SAXException | FileNotFoundException e) {
            LOG.error("讀取文件數據出錯!file:" + file.getPath() + " type:" + type, e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    LOG.error("文件流關閉異常:" + e.getMessage(), e);
                }
            }
        }
        return objResult;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章