package com.genersoft.iot.vmp.gb28181.utils; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; import javax.sip.RequestEvent; import javax.sip.message.Request; import java.io.ByteArrayInputStream; import java.io.StringReader; import java.util.*; /** * 基于dom4j的工具包 * * */ public class XmlUtil { /** * 日志服务 */ private static Logger LOG = LoggerFactory.getLogger(XmlUtil.class); /** * 解析XML为Document对象 * * @param xml 被解析的XMl * * @return Document */ public static Element parseXml(String xml) { Document document = null; // StringReader sr = new StringReader(xml); SAXReader saxReader = new SAXReader(); try { document = saxReader.read(sr); } catch (DocumentException e) { LOG.error("解析失败", e); } return null == document ? null : document.getRootElement(); } /** * 获取element对象的text的值 * * @param em 节点的对象 * @param tag 节点的tag * @return 节点 */ public static String getText(Element em, String tag) { if (null == em) { return null; } Element e = em.element(tag); // return null == e ? null : e.getText().trim(); } /** * 递归解析xml节点,适用于 多节点数据 * * @param node node * @param nodeName nodeName * @return List> */ public static List> listNodes(Element node, String nodeName) { if (null == node) { return null; } // 初始化返回 List> listMap = new ArrayList>(); // 首先获取当前节点的所有属性节点 List list = node.attributes(); Map map = null; // 遍历属性节点 for (Attribute attribute : list) { if (nodeName.equals(node.getName())) { if (null == map) { map = new HashMap(); listMap.add(map); } // 取到的节点属性放到map中 map.put(attribute.getName(), attribute.getValue()); } } // 遍历当前节点下的所有节点 ,nodeName 要解析的节点名称 // 使用递归 Iterator iterator = node.elementIterator(); while (iterator.hasNext()) { Element e = iterator.next(); listMap.addAll(listNodes(e, nodeName)); } return listMap; } /** * xml转json * * @param element * @param json */ public static void node2Json(Element element, JSONObject json) { // 如果是属性 for (Object o : element.attributes()) { Attribute attr = (Attribute) o; if (!StringUtils.isEmpty(attr.getValue())) { json.put("@" + attr.getName(), attr.getValue()); } } List chdEl = element.elements(); if (chdEl.isEmpty() && !StringUtils.isEmpty(element.getText())) {// 如果没有子元素,只有一个值 json.put(element.getName(), element.getText()); } for (Element e : chdEl) { // 有子元素 if (!e.elements().isEmpty()) { // 子元素也有子元素 JSONObject chdjson = new JSONObject(); node2Json(e, chdjson); Object o = json.get(e.getName()); if (o != null) { JSONArray jsona = null; if (o instanceof JSONObject) { // 如果此元素已存在,则转为jsonArray JSONObject jsono = (JSONObject) o; json.remove(e.getName()); jsona = new JSONArray(); jsona.add(jsono); jsona.add(chdjson); } if (o instanceof JSONArray) { jsona = (JSONArray) o; jsona.add(chdjson); } json.put(e.getName(), jsona); } else { if (!chdjson.isEmpty()) { json.put(e.getName(), chdjson); } } } else { // 子元素没有子元素 for (Object o : element.attributes()) { Attribute attr = (Attribute) o; if (!StringUtils.isEmpty(attr.getValue())) { json.put("@" + attr.getName(), attr.getValue()); } } if (!e.getText().isEmpty()) { json.put(e.getName(), e.getText()); } } } } public static Element getRootElement(RequestEvent evt) throws DocumentException { return getRootElement(evt, "gb2312"); } public static Element getRootElement(RequestEvent evt, String charset) throws DocumentException { Request request = evt.getRequest(); return getRootElement(request.getRawContent(), charset); } public static Element getRootElement(byte[] content, String charset) throws DocumentException { if (charset == null) { charset = "gb2312"; } SAXReader reader = new SAXReader(); reader.setEncoding(charset); Document xml = reader.read(new ByteArrayInputStream(content)); return xml.getRootElement(); } public static DeviceChannel channelContentHander(Element itemDevice){ Element channdelNameElement = itemDevice.element("Name"); String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : ""; Element statusElement = itemDevice.element("Status"); String status = statusElement != null ? statusElement.getTextTrim().toString() : "ON"; DeviceChannel deviceChannel = new DeviceChannel(); deviceChannel.setName(channelName); Element channdelIdElement = itemDevice.element("DeviceID"); String channelId = channdelIdElement != null ? channdelIdElement.getTextTrim().toString() : ""; deviceChannel.setChannelId(channelId); // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理 if (status.equals("ON") || status.equals("On") || status.equals("ONLINE") || status.equals("OK")) { deviceChannel.setStatus(1); } if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) { deviceChannel.setStatus(0); } deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer")); deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model")); deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner")); deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode")); deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block")); deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address")); String businessGroupID = XmlUtil.getText(itemDevice, "BusinessGroupID"); if (XmlUtil.getText(itemDevice, "Parental") == null || XmlUtil.getText(itemDevice, "Parental").equals("")) { if (deviceChannel.getChannelId().length() <= 10 || (deviceChannel.getChannelId().length() == 20 && ( Integer.parseInt(deviceChannel.getChannelId().substring(10, 13)) == 215 || Integer.parseInt(deviceChannel.getChannelId().substring(10, 13)) == 216 ) ) ) { deviceChannel.setParental(1); }else { deviceChannel.setParental(0); } } else { // 由于海康会错误的发送65535作为这里的取值,所以这里除非是0否则认为是1 deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")) == 1?1:0); } /** * 行政区划展示设备树与业务分组展示设备树是两种不同的模式 * 行政区划展示设备树 各个目录之间主要靠deviceId做关联,摄像头通过CivilCode指定其属于那个行政区划;都是不超过十位的编号; 结构如下: * 河北省 * --> 石家庄市 * --> 摄像头 * --> 正定县 * --> 摄像头 * --> 摄像头 * * 业务分组展示设备树是顶级是业务分组,其下的虚拟组织靠BusinessGroupID指定其所属的业务分组;摄像头通过ParentId来指定其所属于的虚拟组织: * 业务分组 * --> 虚拟组织 * --> 摄像头 * --> 虚拟组织 * --> 摄像头 * --> 摄像头 */ String parentId = XmlUtil.getText(itemDevice, "ParentID"); if (parentId != null) { if (parentId.contains("/")) { String lastParentId = parentId.substring(parentId.lastIndexOf("/") + 1); deviceChannel.setParentId(lastParentId); }else { deviceChannel.setParentId(parentId); } }else { if (deviceChannel.getChannelId().length() <= 10) { // 此时为行政区划, 上下级行政区划使用DeviceId关联 deviceChannel.setParentId(deviceChannel.getChannelId().substring(0, deviceChannel.getChannelId().length() - 2)); }else if (deviceChannel.getChannelId().length() == 20) { if (Integer.parseInt(deviceChannel.getChannelId().substring(10, 13)) == 216) { // 虚拟组织 deviceChannel.setParentId(businessGroupID); }else if (deviceChannel.getCivilCode() != null) { // 设备, 无parentId的20位是使用CivilCode表示上级的设备, // 注:215 业务分组是需要有parentId的 deviceChannel.setParentId(deviceChannel.getCivilCode()); } }else { deviceChannel.setParentId(deviceChannel.getDeviceId()); } } if (XmlUtil.getText(itemDevice, "SafetyWay") == null || XmlUtil.getText(itemDevice, "SafetyWay") == "") { deviceChannel.setSafetyWay(0); } else { deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay"))); } if (XmlUtil.getText(itemDevice, "RegisterWay") == null || XmlUtil.getText(itemDevice, "RegisterWay") == "") { deviceChannel.setRegisterWay(1); } else { deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay"))); } deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum")); if (XmlUtil.getText(itemDevice, "Certifiable") == null || XmlUtil.getText(itemDevice, "Certifiable") == "") { deviceChannel.setCertifiable(0); } else { deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable"))); } if (XmlUtil.getText(itemDevice, "ErrCode") == null || XmlUtil.getText(itemDevice, "ErrCode") == "") { deviceChannel.setErrCode(0); } else { deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode"))); } deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime")); deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy")); deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress")); if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") == "") { deviceChannel.setPort(0); } else { deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port"))); } deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password")); if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Longitude"))) { deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude"))); } else { deviceChannel.setLongitude(0.00); } if (NumericUtil.isDouble(XmlUtil.getText(itemDevice, "Latitude"))) { deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude"))); } else { deviceChannel.setLatitude(0.00); } if (XmlUtil.getText(itemDevice, "PTZType") == null || "".equals(XmlUtil.getText(itemDevice, "PTZType"))) { //兼容INFO中的信息 Element info = itemDevice.element("Info"); if(XmlUtil.getText(info, "PTZType") == null || "".equals(XmlUtil.getText(info, "PTZType"))){ deviceChannel.setPTZType(0); }else{ deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(info, "PTZType"))); } } else { deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))); } deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC return deviceChannel; } }