改进XmlUtil.xmlToBean,支持xml转bean时父节点忽略大小写

This commit is contained in:
Looly 2023-03-10 13:19:39 +08:00
parent aef20c411d
commit ee57e381b0
3 changed files with 66 additions and 45 deletions

View File

@ -2,10 +2,11 @@
# 🚀Changelog # 🚀Changelog
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
# 5.8.16.M1 (2023-03-09) # 5.8.16.M1 (2023-03-10)
### 🐣新特性 ### 🐣新特性
* 【core 】 改进Calculator.conversion兼容乘法符号省略写法issue#2964@Github * 【core 】 改进Calculator.conversion兼容乘法符号省略写法issue#2964@Github
* 【core 】 改进XmlUtil.xmlToBean支持xml转bean时父节点忽略大小写
### 🐞Bug修复 ### 🐞Bug修复
* 【crypto】 修复NoSuchMethodError未捕获问题issue#2966@Github * 【crypto】 修复NoSuchMethodError未捕获问题issue#2966@Github

View File

@ -982,9 +982,10 @@ public class XmlUtil {
final Map<String, Object> map = xmlToMap(node); final Map<String, Object> map = xmlToMap(node);
if (null != map && map.size() == 1) { if (null != map && map.size() == 1) {
final String simpleName = bean.getSimpleName(); final String simpleName = bean.getSimpleName();
if (map.containsKey(simpleName)) { final String nodeName = CollUtil.getFirst(map.keySet());
if (simpleName.equalsIgnoreCase(nodeName)) {
// 只有key和bean的名称匹配时才做单一对象转换 // 只有key和bean的名称匹配时才做单一对象转换
return BeanUtil.toBean(map.get(simpleName), bean); return BeanUtil.toBean(map.get(nodeName), bean);
} }
} }
return BeanUtil.toBean(map, bean); return BeanUtil.toBean(map, bean);

View File

@ -30,7 +30,7 @@ public class XmlUtilTest {
@Test @Test
public void parseTest() { public void parseTest() {
String result = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"// final String result = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"//
+ "<returnsms>"// + "<returnsms>"//
+ "<returnstatus>Success</returnstatus>"// + "<returnstatus>Success</returnstatus>"//
+ "<message>ok</message>"// + "<message>ok</message>"//
@ -38,15 +38,15 @@ public class XmlUtilTest {
+ "<taskID>885</taskID>"// + "<taskID>885</taskID>"//
+ "<successCounts>1</successCounts>"// + "<successCounts>1</successCounts>"//
+ "</returnsms>"; + "</returnsms>";
Document docResult = XmlUtil.parseXml(result); final Document docResult = XmlUtil.parseXml(result);
String elementText = XmlUtil.elementText(docResult.getDocumentElement(), "returnstatus"); final String elementText = XmlUtil.elementText(docResult.getDocumentElement(), "returnstatus");
Assert.assertEquals("Success", elementText); Assert.assertEquals("Success", elementText);
} }
@Test @Test
@Ignore @Ignore
public void writeTest() { public void writeTest() {
String result = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"// final String result = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"//
+ "<returnsms>"// + "<returnsms>"//
+ "<returnstatus>Success成功</returnstatus>"// + "<returnstatus>Success成功</returnstatus>"//
+ "<message>ok</message>"// + "<message>ok</message>"//
@ -54,13 +54,13 @@ public class XmlUtilTest {
+ "<taskID>885</taskID>"// + "<taskID>885</taskID>"//
+ "<successCounts>1</successCounts>"// + "<successCounts>1</successCounts>"//
+ "</returnsms>"; + "</returnsms>";
Document docResult = XmlUtil.parseXml(result); final Document docResult = XmlUtil.parseXml(result);
XmlUtil.toFile(docResult, "e:/aaa.xml", "utf-8"); XmlUtil.toFile(docResult, "e:/aaa.xml", "utf-8");
} }
@Test @Test
public void xpathTest() { public void xpathTest() {
String result = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"// final String result = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"//
+ "<returnsms>"// + "<returnsms>"//
+ "<returnstatus>Success成功</returnstatus>"// + "<returnstatus>Success成功</returnstatus>"//
+ "<message>ok</message>"// + "<message>ok</message>"//
@ -68,22 +68,22 @@ public class XmlUtilTest {
+ "<taskID>885</taskID>"// + "<taskID>885</taskID>"//
+ "<successCounts>1</successCounts>"// + "<successCounts>1</successCounts>"//
+ "</returnsms>"; + "</returnsms>";
Document docResult = XmlUtil.parseXml(result); final Document docResult = XmlUtil.parseXml(result);
Object value = XmlUtil.getByXPath("//returnsms/message", docResult, XPathConstants.STRING); final Object value = XmlUtil.getByXPath("//returnsms/message", docResult, XPathConstants.STRING);
Assert.assertEquals("ok", value); Assert.assertEquals("ok", value);
} }
@Test @Test
public void xpathTest2() { public void xpathTest2() {
String result = ResourceUtil.readUtf8Str("test.xml"); final String result = ResourceUtil.readUtf8Str("test.xml");
Document docResult = XmlUtil.parseXml(result); final Document docResult = XmlUtil.parseXml(result);
Object value = XmlUtil.getByXPath("//returnsms/message", docResult, XPathConstants.STRING); final Object value = XmlUtil.getByXPath("//returnsms/message", docResult, XPathConstants.STRING);
Assert.assertEquals("ok", value); Assert.assertEquals("ok", value);
} }
@Test @Test
public void xmlToMapTest() { public void xmlToMapTest() {
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"// final String xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"//
+ "<returnsms>"// + "<returnsms>"//
+ "<returnstatus>Success</returnstatus>"// + "<returnstatus>Success</returnstatus>"//
+ "<message>ok</message>"// + "<message>ok</message>"//
@ -92,7 +92,7 @@ public class XmlUtilTest {
+ "<successCounts>1</successCounts>"// + "<successCounts>1</successCounts>"//
+ "<newNode><sub>subText</sub></newNode>"// + "<newNode><sub>subText</sub></newNode>"//
+ "</returnsms>"; + "</returnsms>";
Map<String, Object> map = XmlUtil.xmlToMap(xml); final Map<String, Object> map = XmlUtil.xmlToMap(xml);
Assert.assertEquals(6, map.size()); Assert.assertEquals(6, map.size());
Assert.assertEquals("Success", map.get("returnstatus")); Assert.assertEquals("Success", map.get("returnstatus"));
@ -105,8 +105,8 @@ public class XmlUtilTest {
@Test @Test
public void xmlToMapTest2() { public void xmlToMapTest2() {
String xml = "<root><name>张三</name><name>李四</name></root>"; final String xml = "<root><name>张三</name><name>李四</name></root>";
Map<String, Object> map = XmlUtil.xmlToMap(xml); final Map<String, Object> map = XmlUtil.xmlToMap(xml);
Assert.assertEquals(1, map.size()); Assert.assertEquals(1, map.size());
Assert.assertEquals(CollUtil.newArrayList("张三", "李四"), map.get("name")); Assert.assertEquals(CollUtil.newArrayList("张三", "李四"), map.get("name"));
@ -114,12 +114,12 @@ public class XmlUtilTest {
@Test @Test
public void mapToXmlTest() { public void mapToXmlTest() {
Map<String, Object> map = MapBuilder.create(new LinkedHashMap<String, Object>())// final Map<String, Object> map = MapBuilder.create(new LinkedHashMap<String, Object>())//
.put("name", "张三")// .put("name", "张三")//
.put("age", 12)// .put("age", 12)//
.put("game", MapUtil.builder(new LinkedHashMap<String, Object>()).put("昵称", "Looly").put("level", 14).build())// .put("game", MapUtil.builder(new LinkedHashMap<String, Object>()).put("昵称", "Looly").put("level", 14).build())//
.build(); .build();
Document doc = XmlUtil.mapToXml(map, "user"); final Document doc = XmlUtil.mapToXml(map, "user");
// Console.log(XmlUtil.toStr(doc, false)); // Console.log(XmlUtil.toStr(doc, false));
Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"// Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"//
+ "<user>"// + "<user>"//
@ -136,11 +136,11 @@ public class XmlUtilTest {
@Test @Test
public void mapToXmlTest2() { public void mapToXmlTest2() {
// 测试List // 测试List
Map<String, Object> map = MapBuilder.create(new LinkedHashMap<String, Object>()) final Map<String, Object> map = MapBuilder.create(new LinkedHashMap<String, Object>())
.put("Town", CollUtil.newArrayList("town1", "town2")) .put("Town", CollUtil.newArrayList("town1", "town2"))
.build(); .build();
Document doc = XmlUtil.mapToXml(map, "City"); final Document doc = XmlUtil.mapToXml(map, "City");
Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + Assert.assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
"<City>" + "<City>" +
"<Town>town1</Town>" + "<Town>town1</Town>" +
@ -151,7 +151,7 @@ public class XmlUtilTest {
@Test @Test
public void readTest() { public void readTest() {
Document doc = XmlUtil.readXML("test.xml"); final Document doc = XmlUtil.readXML("test.xml");
Assert.assertNotNull(doc); Assert.assertNotNull(doc);
} }
@ -161,7 +161,7 @@ public class XmlUtilTest {
"returnsms", "returnstatus", "message", "remainpoint", "taskID", "successCounts"); "returnsms", "returnstatus", "message", "remainpoint", "taskID", "successCounts");
XmlUtil.readBySax(ResourceUtil.getStream("test.xml"), new DefaultHandler(){ XmlUtil.readBySax(ResourceUtil.getStream("test.xml"), new DefaultHandler(){
@Override @Override
public void startElement(String uri, String localName, String qName, Attributes attributes) { public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) {
Assert.assertTrue(eles.contains(localName)); Assert.assertTrue(eles.contains(localName));
} }
}); });
@ -170,16 +170,16 @@ public class XmlUtilTest {
@Test @Test
public void mapToXmlTestWithOmitXmlDeclaration() { public void mapToXmlTestWithOmitXmlDeclaration() {
Map<String, Object> map = MapBuilder.create(new LinkedHashMap<String, Object>()) final Map<String, Object> map = MapBuilder.create(new LinkedHashMap<String, Object>())
.put("name", "ddatsh") .put("name", "ddatsh")
.build(); .build();
String xml = XmlUtil.mapToXmlStr(map, true); final String xml = XmlUtil.mapToXmlStr(map, true);
Assert.assertEquals("<xml><name>ddatsh</name></xml>", xml); Assert.assertEquals("<xml><name>ddatsh</name></xml>", xml);
} }
@Test @Test
public void getByPathTest() { public void getByPathTest() {
String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + final String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
" <soap:Body>\n" + " <soap:Body>\n" +
" <ns2:testResponse xmlns:ns2=\"http://ws.xxx.com/\">\n" + " <ns2:testResponse xmlns:ns2=\"http://ws.xxx.com/\">\n" +
@ -188,8 +188,8 @@ public class XmlUtilTest {
" </soap:Body>\n" + " </soap:Body>\n" +
"</soap:Envelope>\n"; "</soap:Envelope>\n";
Document document = XmlUtil.readXML(xmlStr); final Document document = XmlUtil.readXML(xmlStr);
Object value = XmlUtil.getByXPath( final Object value = XmlUtil.getByXPath(
"//soap:Envelope/soap:Body/ns2:testResponse/return", "//soap:Envelope/soap:Body/ns2:testResponse/return",
document, XPathConstants.STRING);// document, XPathConstants.STRING);//
Assert.assertEquals("2020/04/15 21:01:21", value); Assert.assertEquals("2020/04/15 21:01:21", value);
@ -259,17 +259,17 @@ public class XmlUtilTest {
} }
//issue#1663@Github //issue#1663@Github
String xmlStr = "<?xml version=\"1.0\" encoding=\"gbk\" ?><response><code>02</code></response>"; final String xmlStr = "<?xml version=\"1.0\" encoding=\"gbk\" ?><response><code>02</code></response>";
Document doc = XmlUtil.parseXml(xmlStr); final Document doc = XmlUtil.parseXml(xmlStr);
// 标准方式 // 标准方式
Map<String, Object> map = XmlUtil.xmlToMap(doc.getFirstChild()); final Map<String, Object> map = XmlUtil.xmlToMap(doc.getFirstChild());
SmsRes res = new SmsRes(); final SmsRes res = new SmsRes();
BeanUtil.fillBeanWithMap(map, res, true); BeanUtil.fillBeanWithMap(map, res, true);
// toBean方式 // toBean方式
SmsRes res1 = XmlUtil.xmlToBean(doc.getFirstChild(), SmsRes.class); final SmsRes res1 = XmlUtil.xmlToBean(doc.getFirstChild(), SmsRes.class);
Assert.assertEquals(res.toString(), res1.toString()); Assert.assertEquals(res.toString(), res1.toString());
} }
@ -285,22 +285,22 @@ public class XmlUtilTest {
@Ignore @Ignore
public void formatTest(){ public void formatTest(){
// https://github.com/looly/hutool/pull/1234 // https://github.com/looly/hutool/pull/1234
Document xml = XmlUtil.createXml("NODES"); final Document xml = XmlUtil.createXml("NODES");
xml.setXmlStandalone(true); xml.setXmlStandalone(true);
NodeList parentNode = xml.getElementsByTagName("NODES"); final NodeList parentNode = xml.getElementsByTagName("NODES");
Element parent1Node = xml.createElement("NODE"); final Element parent1Node = xml.createElement("NODE");
Element node1 = xml.createElement("NODENAME"); final Element node1 = xml.createElement("NODENAME");
node1.setTextContent("走位"); node1.setTextContent("走位");
Element node2 = xml.createElement("STEP"); final Element node2 = xml.createElement("STEP");
node2.setTextContent("1"); node2.setTextContent("1");
Element node3 = xml.createElement("STATE"); final Element node3 = xml.createElement("STATE");
node3.setTextContent("2"); node3.setTextContent("2");
Element node4 = xml.createElement("TIMELIMIT"); final Element node4 = xml.createElement("TIMELIMIT");
node4.setTextContent(""); node4.setTextContent("");
Element node5 = xml.createElement("STARTTIME"); final Element node5 = xml.createElement("STARTTIME");
parent1Node.appendChild(node1); parent1Node.appendChild(node1);
parent1Node.appendChild(node2); parent1Node.appendChild(node2);
@ -310,20 +310,20 @@ public class XmlUtilTest {
parentNode.item(0).appendChild(parent1Node); parentNode.item(0).appendChild(parent1Node);
String format = XmlUtil.toStr(xml,"GBK",true); final String format = XmlUtil.toStr(xml,"GBK",true);
Console.log(format); Console.log(format);
} }
@Test @Test
public void escapeTest(){ public void escapeTest(){
String a = "<>"; final String a = "<>";
final String escape = XmlUtil.escape(a); final String escape = XmlUtil.escape(a);
Console.log(escape); Console.log(escape);
} }
@Test @Test
public void getParamTest(){ public void getParamTest(){
String xml = "<Config name=\"aaaa\">\n" + final String xml = "<Config name=\"aaaa\">\n" +
" <url>222222</url>\n" + " <url>222222</url>\n" +
"</Config>"; "</Config>";
@ -331,4 +331,23 @@ public class XmlUtilTest {
final String name = doc.getDocumentElement().getAttribute("name"); final String name = doc.getDocumentElement().getAttribute("name");
Assert.assertEquals("aaaa", name); Assert.assertEquals("aaaa", name);
} }
@Test
public void xmlStrToBeanTest(){
final String xml = "<userInfo><name>张三</name><age>20</age><email>zhangsan@example.com</email></userInfo>";
final Document document = XmlUtil.readXML(xml);
final UserInfo userInfo = XmlUtil.xmlToBean(document, UserInfo.class);
Assert.assertEquals("张三", userInfo.getName());
Assert.assertEquals("20", userInfo.getAge());
Assert.assertEquals("zhangsan@example.com", userInfo.getEmail());
}
@Data
static class UserInfo {
private String id;
private String name;
private String age;
private String email;
}
} }