add readBySax

This commit is contained in:
Looly 2020-09-30 11:30:10 +08:00
parent f6a18afcba
commit 61c0633da7
3 changed files with 113 additions and 0 deletions

View File

@ -32,6 +32,7 @@
* 【core 】 NumberUtil增加isPowerOfTwo方法pr#1132@Github
* 【core 】 优化BooleanUtil的校验逻辑pr#1137@Github
* 【poi 】 改进sax方式读取逻辑支持sheetIdissue#1141@Github
* 【core 】 XmlUtil增加readBySax方法
### Bug修复
* 【crypto 】 修复SM2验签后无法解密问题issue#I1W0VP@Gitee

View File

@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.BiMap;
@ -13,7 +14,11 @@ import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
@ -21,6 +26,8 @@ import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
@ -76,6 +83,10 @@ public class XmlUtil {
* 是否打开命名空间支持
*/
private static boolean namespaceAware = true;
/**
* Sax读取器工厂缓存
*/
private static SAXParserFactory factory;
/**
* 禁用默认的DocumentBuilderFactory禁用后如果有第三方的实现如oracle的xdb包中的xmlparse将会自动加载实现
@ -184,6 +195,92 @@ public class XmlUtil {
}
}
/**
* 使用Sax方式读取指定的XML<br>
* 如果用户传入的contentHandler为{@link DefaultHandler}则其接口都会被处理
*
* @param file XML源文件,使用后自动关闭
* @param contentHandler XML流处理器用于按照Element处理xml
* @since 5.4.4
*/
public static void readBySax(File file, ContentHandler contentHandler) {
InputStream in = null;
try{
in = FileUtil.getInputStream(file);
readBySax(new InputSource(in), contentHandler);
} finally {
IoUtil.close(in);
}
}
/**
* 使用Sax方式读取指定的XML<br>
* 如果用户传入的contentHandler为{@link DefaultHandler}则其接口都会被处理
*
* @param reader XML源Reader,使用后自动关闭
* @param contentHandler XML流处理器用于按照Element处理xml
* @since 5.4.4
*/
public static void readBySax(Reader reader, ContentHandler contentHandler) {
try{
readBySax(new InputSource(reader), contentHandler);
} finally {
IoUtil.close(reader);
}
}
/**
* 使用Sax方式读取指定的XML<br>
* 如果用户传入的contentHandler为{@link DefaultHandler}则其接口都会被处理
*
* @param source XML源流,使用后自动关闭
* @param contentHandler XML流处理器用于按照Element处理xml
* @since 5.4.4
*/
public static void readBySax(InputStream source, ContentHandler contentHandler) {
try{
readBySax(new InputSource(source), contentHandler);
} finally {
IoUtil.close(source);
}
}
/**
* 使用Sax方式读取指定的XML<br>
* 如果用户传入的contentHandler为{@link DefaultHandler}则其接口都会被处理
*
* @param source XML源可以是文件路径等
* @param contentHandler XML流处理器用于按照Element处理xml
* @since 5.4.4
*/
public static void readBySax(InputSource source, ContentHandler contentHandler) {
// 1.获取解析工厂
if (null == factory) {
factory = SAXParserFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(namespaceAware);
}
// 2.从解析工厂获取解析器
final SAXParser parse;
XMLReader reader;
try {
parse = factory.newSAXParser();
if (contentHandler instanceof DefaultHandler) {
parse.parse(source, (DefaultHandler) contentHandler);
return;
}
// 3.得到解读器
reader = parse.getXMLReader();
reader.setContentHandler(contentHandler);
reader.parse(source);
} catch (ParserConfigurationException | SAXException e) {
throw new UtilException(e);
} catch (IOException e) {
throw new IORuntimeException(e);
}
}
/**
* 将String类型的XML转换为XML文档
*

View File

@ -9,10 +9,13 @@ import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.xpath.XPathConstants;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
/**
* {@link XmlUtil} 工具类
@ -148,6 +151,18 @@ public class XmlUtilTest {
Assert.assertNotNull(doc);
}
@Test
public void readBySaxTest(){
final Set<String> eles = CollUtil.newHashSet(
"returnsms", "returnstatus", "message", "remainpoint", "taskID", "successCounts");
XmlUtil.readBySax(ResourceUtil.getStream("test.xml"), new DefaultHandler(){
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) {
Assert.assertTrue(eles.contains(localName));
}
});
}
@Test
public void mapToXmlTestWithOmitXmlDeclaration() {