|
@@ -0,0 +1,424 @@
|
|
|
+package com.lantone.qc.dbanaly.facade.yiwu;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.google.common.collect.ImmutableMap;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import com.google.common.collect.Maps;
|
|
|
+import com.lantone.qc.pub.util.FileUtil;
|
|
|
+import com.lantone.qc.pub.util.MapUtil;
|
|
|
+import com.lantone.qc.pub.util.StringUtil;
|
|
|
+import org.dom4j.Document;
|
|
|
+import org.dom4j.DocumentHelper;
|
|
|
+import org.dom4j.Element;
|
|
|
+
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @Description: xml解析工具
|
|
|
+ * @author: rengb
|
|
|
+ * @time: 2020/3/28 14:23
|
|
|
+ */
|
|
|
+public class YiWuFirstPageRecordXmlUtil {
|
|
|
+ public static Map<String, String> leaveDiagMap = ImmutableMap.<String, String>builder()
|
|
|
+ .put("出院诊断", "诊断名称")
|
|
|
+ .put("出院诊断编码", "诊断编码")
|
|
|
+ .put("出院诊断_入院病情", "入院情况")
|
|
|
+ .put("诊断类型", "出院情况")
|
|
|
+ .build();
|
|
|
+
|
|
|
+ public static Map<String, String> operationMap = ImmutableMap.<String, String>builder()
|
|
|
+ .put("手术名称", "手术名称")
|
|
|
+ .put("手术开始日期", "手术日期")
|
|
|
+ .put("手术切口愈合等级", "愈合等级")
|
|
|
+ .put("手术及操作编码", "手术编码")
|
|
|
+ .put("手术级别", "手术级别")
|
|
|
+ .put("手术切口等级", "切口等级")
|
|
|
+ .put("主刀医师", "手术医生ID")
|
|
|
+ .put("Ⅰ助姓名", "一助医生ID")
|
|
|
+ .put("Ⅱ助姓名", "二助医生ID")
|
|
|
+ .put("麻醉方式", "麻醉方式")
|
|
|
+ .put("麻醉医师签名", "麻醉医师")
|
|
|
+ .build();
|
|
|
+
|
|
|
+ public static Map<String, Object> process(String xml) {
|
|
|
+ Map<String, String> sourceMap = xmlToMap(xml);
|
|
|
+ Map<String, String> structureMap = mapKeyContrast(sourceMap, keyContrasts);
|
|
|
+ Map<String, Object> structureExtMap = Maps.newHashMap();
|
|
|
+ structureExtMap.putAll(structureMap);
|
|
|
+ JSONArray leaveDiags = new JSONArray();
|
|
|
+ specialProcess(structureMap, leaveDiagMap, leaveDiags);
|
|
|
+ structureExtMap.put("出院诊断", leaveDiags);
|
|
|
+
|
|
|
+ JSONArray operations = new JSONArray();
|
|
|
+ specialProcess(structureMap, operationMap, operations);
|
|
|
+ structureExtMap.put("手术信息", operations);
|
|
|
+ return structureExtMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Map<String, String> xmlToMap(String xml) {
|
|
|
+ Map<String, String> map = Maps.newHashMap();
|
|
|
+ try {
|
|
|
+ Document doc = DocumentHelper.parseText(xml);
|
|
|
+ Element root = (Element) doc.selectSingleNode("//XTextDocument/XElements/Element[@xsi:type='XTextBody']/XElements");
|
|
|
+ findElement(root, "XInputField").forEach(i -> {
|
|
|
+ xInputField(map, i, null);
|
|
|
+ });
|
|
|
+ findElement(root, "XTextTable").forEach(tableElement -> {
|
|
|
+ String tablePreTxt = getElementPreVal(tableElement);
|
|
|
+ findElement(tableElement.element("XElements"), "XTextTableRow").forEach(rowElement -> {
|
|
|
+ findElement(rowElement.element("XElements"), "XTextTableCell").forEach(cellElement -> {
|
|
|
+ List<Element> xTextTable = findElement(cellElement.element("XElements"), "XTextTable");
|
|
|
+ if (xTextTable.size() > 0) {
|
|
|
+ xTextTable.forEach(stableElement -> {
|
|
|
+ String stablePreTxt = getElementPreVal(stableElement);
|
|
|
+ findElement(stableElement.element("XElements"), "XTextTableRow").forEach(srowElement -> {
|
|
|
+ findElement(srowElement.element("XElements"), "XTextTableCell").forEach(scellElement -> {
|
|
|
+ findElement(scellElement.element("XElements"), "XInputField").forEach(xInputFieldElement -> {
|
|
|
+ xInputField(map, xInputFieldElement, stablePreTxt);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ findElement(cellElement.element("XElements"), "XInputField").forEach(xInputFieldElement -> {
|
|
|
+ xInputField(map, xInputFieldElement, tablePreTxt);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ Element bodyTextElement = (Element) doc.selectSingleNode("//XTextDocument/BodyText");
|
|
|
+ String bodyText = bodyTextElement.getText();
|
|
|
+ map.put("原始文本", bodyText);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ map.clear();
|
|
|
+ }
|
|
|
+ // map.keySet().forEach(key -> {
|
|
|
+ // System.out.println(key + "----" + map.get(key));
|
|
|
+ // });
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static List<Element> findElement(Element element, String attual) {
|
|
|
+ List<Element> ret = Lists.newArrayList();
|
|
|
+ ((List<Element>) (element.elements())).forEach(i -> {
|
|
|
+ if (StringUtil.isNotBlank(i.attributeValue("type")) && i.attributeValue("type").equals(attual)) {
|
|
|
+ ret.add(i);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void xInputField(Map<String, String> map, Element xInputFieldElement, String tablePreTxt) {
|
|
|
+ String value = getXInputFieldValue(xInputFieldElement);
|
|
|
+ if (value == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String key = getXInputFieldKey(xInputFieldElement, tablePreTxt);
|
|
|
+ if (StringUtil.isNotBlank(key)) {
|
|
|
+ if (map.containsKey(key)) {
|
|
|
+ value = map.get(key) + " " + value;
|
|
|
+ }
|
|
|
+ map.put(key, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取 XInputField 的键
|
|
|
+ private static String getXInputFieldKey(Element xInputFieldElement, String tablePreTxt) {
|
|
|
+ String key = null;
|
|
|
+ String[] elementNames = { "Name", "BackgroundText", "ToolTip" };
|
|
|
+ for (String elementName : elementNames) {
|
|
|
+ key = xInputFieldElement.elementTextTrim(elementName);
|
|
|
+ if (StringUtil.isNotBlank(key)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtil.isBlank(key)) {
|
|
|
+ key = getElementPreVal(xInputFieldElement);
|
|
|
+ }
|
|
|
+ if (StringUtil.isBlank(key)) {
|
|
|
+ key = tablePreTxt;
|
|
|
+ }
|
|
|
+ if (StringUtil.isBlank(key)) {
|
|
|
+ key = "病历内容";
|
|
|
+ }
|
|
|
+ return keyHandle(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取 XInputField 的值
|
|
|
+ private static String getXInputFieldValue(Element xInputFieldElement) {
|
|
|
+ String value = null;
|
|
|
+ Element innerValueElement = xInputFieldElement.element("InnerValue");
|
|
|
+ if (innerValueElement != null) {
|
|
|
+ value = innerValueElement.getTextTrim();
|
|
|
+ }
|
|
|
+ if (StringUtil.isBlank(value)) {
|
|
|
+ Element xElementsElement = xInputFieldElement.element("XElements");
|
|
|
+ if (xElementsElement != null) {
|
|
|
+ List<Element> elements = findElement(xElementsElement, "XString");
|
|
|
+ if (elements.size() > 0) {
|
|
|
+ value = "";
|
|
|
+ for (Element element : elements) {
|
|
|
+ Element text = element.element("Text");
|
|
|
+ if (text != null) {
|
|
|
+ value += text.getTextTrim();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtil.isBlank(value)) {
|
|
|
+ innerValueElement = xInputFieldElement.element("BackgroundText");
|
|
|
+ if (innerValueElement != null) {
|
|
|
+ value = innerValueElement.getTextTrim();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtil.isBlank(value)) {
|
|
|
+ value = "";
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取前面文本信息作为key
|
|
|
+ private static String getElementPreVal(Element xInputFieldElement) {
|
|
|
+ String ret = "";
|
|
|
+ List<Element> sonElements = xInputFieldElement.getParent().elements();
|
|
|
+ int index = sonElements.indexOf(xInputFieldElement);
|
|
|
+ for (int i = index - 1; i >= 0; i--) {
|
|
|
+ Element sonElement = sonElements.get(i);
|
|
|
+ if (sonElement.attributeValue("type").equals("XTextTable") || sonElement.attributeValue("type").equals("XInputField")) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (sonElement.attributeValue("type").equals("XString")) {
|
|
|
+ ret = sonElement.elementTextTrim("Text") + ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ //针对key的一些特殊处理
|
|
|
+ private static String keyHandle(String key) {
|
|
|
+ key = StringUtil.removeBlank(key).replaceAll("[::]", "");
|
|
|
+ return key;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据给定key映射
|
|
|
+ *
|
|
|
+ * @param sourceMap
|
|
|
+ * @param keyContrasts
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static Map<String, String> mapKeyContrast(Map<String, String> sourceMap, List<String> keyContrasts) {
|
|
|
+ Map<String, String> retMap = Maps.newHashMap();
|
|
|
+ mapKeyContrastCommon(sourceMap, keyContrasts, retMap);
|
|
|
+ return retMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
|
|
|
+ Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
|
|
|
+ String[] arry = null;
|
|
|
+ String sourceKey = null, targetKey;
|
|
|
+ Set<String> removeKey = new HashSet<>();
|
|
|
+ for (String keyContrast : keyContrasts) {
|
|
|
+ arry = keyContrast.split("=");
|
|
|
+ sourceKey = arry[0];
|
|
|
+ if (arry.length == 1) {
|
|
|
+ targetKey = arry[0];
|
|
|
+ } else {
|
|
|
+ targetKey = arry[1];
|
|
|
+ }
|
|
|
+ if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
|
|
|
+ && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
|
|
|
+ retMap.put(targetKey, sourceMap_.get(sourceKey));
|
|
|
+ }
|
|
|
+ removeKey.add(sourceKey);
|
|
|
+ // sourceMap_.remove(sourceKey); // 如果直接remove,多个标准key对应xml中同一个key就会出问题
|
|
|
+ }
|
|
|
+ // retMap.putAll(sourceMap_); //如果key相同会覆盖之前的值,存在bug
|
|
|
+ Set<String> keySet = retMap.keySet();
|
|
|
+ for (String key : sourceMap_.keySet()) {
|
|
|
+ if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
|
|
|
+ retMap.put(key, sourceMap_.get(key));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 特殊处理病案首页中出院诊断、手术
|
|
|
+ *
|
|
|
+ * @param structureMap
|
|
|
+ * @param leaveDiagMap
|
|
|
+ * @param array
|
|
|
+ */
|
|
|
+ public static void specialProcess(Map<String, String> structureMap, Map<String, String> leaveDiagMap, JSONArray array) {
|
|
|
+ JSONObject object;
|
|
|
+ int num = 0;
|
|
|
+ try {
|
|
|
+ for (Map.Entry<String, String> entry : leaveDiagMap.entrySet()) {
|
|
|
+ if (structureMap.containsKey(entry.getKey())) {
|
|
|
+ String value = structureMap.get(entry.getKey());
|
|
|
+ value = removeUseless(value);
|
|
|
+ String[] values = value.split(" ");
|
|
|
+ if (num == 0) {
|
|
|
+ for (String v : values) {
|
|
|
+ object = new JSONObject();
|
|
|
+ object.put(entry.getValue(), v);
|
|
|
+ array.add(object);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ boolean flag = false;
|
|
|
+ if ("诊断类型".equals(entry.getKey()) && values[0].contains("诊断")) {
|
|
|
+ array.getJSONObject(0).put("诊断类别", values[0].replace(":", ""));
|
|
|
+ flag = true;
|
|
|
+ }
|
|
|
+ for (int i = 0; i < array.size(); i++) {
|
|
|
+ if (flag) {
|
|
|
+ array.getJSONObject(i).put(entry.getValue(), values[i + 1]);
|
|
|
+ } else {
|
|
|
+ array.getJSONObject(i).put(entry.getValue(), values[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ num++;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.getMessage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 去除末尾没用的“ -”或“ -”
|
|
|
+ *
|
|
|
+ * @param value
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String removeUseless(String value) {
|
|
|
+ while (value.endsWith(" -") || value.endsWith(" -")) {
|
|
|
+ value = value.substring(0, value.length() - 2);
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ xmlToMap(FileUtil.fileRead("C:\\Users\\Administrator\\Desktop\\义务\\jiexi\\n5.xml"));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> keyContrasts = Lists.newArrayList(
|
|
|
+ "过敏源=过敏药物",
|
|
|
+ "患者姓名=姓名",
|
|
|
+ "出院日期=出院时间",
|
|
|
+ "颅脑损伤患者入院后昏迷时间_天=颅脑损伤患者昏迷后天数",
|
|
|
+ "耗材类_检查用一次性医用材料费=检查用一次性医用材料费",
|
|
|
+ "联系人电话号码=联系人电话",
|
|
|
+ "入院途径=入院途径",
|
|
|
+ "婚姻状况=婚姻",
|
|
|
+ "入院科室=入院科别",
|
|
|
+ "治疗类_非手术治疗项目费=非手术治疗项目费",
|
|
|
+ "转科科别=转科科别",
|
|
|
+ "Rh血型=Rh",
|
|
|
+ "住院总费用_自付金额=自付金额",
|
|
|
+ "诊断符合情况_术前与术后=术前与术后",
|
|
|
+ "出院科室=出院科别",
|
|
|
+ "康复类_康复费=康复类",
|
|
|
+ "户口地址邮编=户口地址邮编",
|
|
|
+ "病案质量=病案质量",
|
|
|
+ "质控护士=质控护士",
|
|
|
+ "离院方式=离院方式",
|
|
|
+ "诊断符合情况_入院与出院=入院与出院",
|
|
|
+ "住院医师=住院医师",
|
|
|
+ "联系人姓名=联系人姓名",
|
|
|
+ "中医治疗费=中医治疗费",
|
|
|
+ "诊断符合情况_门诊与住院=门诊与住院",
|
|
|
+ "入院病房=入院病房",
|
|
|
+ "质控日期=质控日期",
|
|
|
+ "医疗机构代码=",
|
|
|
+ "颅脑损伤患者入院前昏迷时间_天=颅脑损伤患者昏迷前天数",
|
|
|
+ "治疗类_手术治疗费_麻醉费=麻醉费",
|
|
|
+ "婴儿年龄=",
|
|
|
+ "职业=职业",
|
|
|
+ "户口地址_其它=户口地址其它",
|
|
|
+ "出院病房=出院病房",
|
|
|
+ "综合医疗服务类_一般治疗操作费=一般治疗服务费",
|
|
|
+ "质控医师=质控医师",
|
|
|
+ "西药类_西药费=西药费",
|
|
|
+ "现住址_市=",
|
|
|
+ "病理诊断编码=病理诊断编码",
|
|
|
+ "责任护士111=责任护士",
|
|
|
+ "出院31天内再住院目的=再住院目的",
|
|
|
+ "现住址_省=",
|
|
|
+ "损伤中毒外部因素编码=损伤中毒因素编码",
|
|
|
+ "诊断类_影像学诊断费=影像学诊断费",
|
|
|
+ "体重11111=体重",
|
|
|
+ "转入医疗机构科室=接收机构名称",
|
|
|
+ "中药类_中成药费=中成药费",
|
|
|
+ "身份证件号码=身份证号",
|
|
|
+ "入院日期=入院时间",
|
|
|
+ "进修医师=进修医师",
|
|
|
+ "治疗类_手术治疗费=手术治疗费",
|
|
|
+ "血液和血液制品类_血费=血费",
|
|
|
+ "治疗类_手术治疗费_手术费=手术治疗费",
|
|
|
+ "血液和血液制品类_球蛋白类制品费=球蛋白类制品费",
|
|
|
+ "病理诊断=病理诊断",
|
|
|
+ "出院31天内再住院计划=三十一天内再住院计划",
|
|
|
+ "血液和血液制品类_凝血因子类制品费=凝血因子类制品费",
|
|
|
+ "工作单位电话=工作单位电话",
|
|
|
+ "药物过敏标志=药物过敏",
|
|
|
+ "联系电话=现住址电话",
|
|
|
+ "损伤中毒外部因素=损伤中毒因素",
|
|
|
+ "诊断类_实验室诊断费=实验室诊断费",
|
|
|
+ "年龄=新生儿年龄",
|
|
|
+ "诊断类_临床诊断项目费=临床诊断项目费",
|
|
|
+ "耗材类_治疗用一次性医用材料费=治疗用一次性医用材料费",
|
|
|
+ "诊断符合情况_临床与病理=临床与病理",
|
|
|
+ "诊断类_病理诊断费=病理诊断费",
|
|
|
+ "其他类_其他费=其他类其他费",
|
|
|
+ "患者工作单位地址=工作单位",
|
|
|
+ "死亡患者尸检标志=死亡患者尸检",
|
|
|
+ "现住址_其它=现住址其它",
|
|
|
+ "血液和血液制品类_白蛋白类制品费=白蛋白类制品费",
|
|
|
+ "综合医疗服务类_其他费用=其他费用",
|
|
|
+ "医疗付费方式代码=",
|
|
|
+ "医疗付费方式=",
|
|
|
+ "综合医疗服务类_护理费=护理费",
|
|
|
+ "(副)主任11=",
|
|
|
+ "住院总费用=总费用",
|
|
|
+ "门诊诊断=门急诊诊断",
|
|
|
+ "主治医生AAA=",
|
|
|
+ "现住址邮编=现住址邮编",
|
|
|
+ "颅脑损伤患者入院前昏迷时间_分=颅脑损伤患者昏迷前分钟",
|
|
|
+ "西药类_西药费_抗菌药物费用=抗菌药物费用",
|
|
|
+ "新生儿出生体重=新生儿出生体重",
|
|
|
+ "民族=民族",
|
|
|
+ "颅脑损伤患者入院后昏迷时间_时=颅脑损伤患者昏迷后小时",
|
|
|
+ "住院天数=实际住院天数",
|
|
|
+ "耗材类_手术用一次性医用材料费=手术用一次性医用材料费",
|
|
|
+ "ABO血型=血型",
|
|
|
+ "颅脑损伤患者入院前昏迷时间_时=颅脑损伤患者昏迷前小时",
|
|
|
+ "联系人住址=联系人地址",
|
|
|
+ "综合医疗服务类_一般医疗服务费=一般医疗服务费",
|
|
|
+ "血液和血液制品类_细胞因子类制品费=细胞因子类制品费",
|
|
|
+ "编码员=编码员",
|
|
|
+ "治疗类_非手术治疗项目费_临床物理治疗费=临床物理治疗费",
|
|
|
+ "颅脑损伤患者入院后昏迷时间_分=颅脑损伤患者昏迷后分钟",
|
|
|
+ "住院次数=",
|
|
|
+ "性别=性别",
|
|
|
+ "诊断符合情况_放射与病理=放射与病理",
|
|
|
+ "转入医疗机构_乡镇社区=接收机构名称",
|
|
|
+ "病案号=",
|
|
|
+ "中药类_中草药费=中草药费",
|
|
|
+ "出生日期=出生日期",
|
|
|
+ "联系人关系=联系人关系",
|
|
|
+ "科主任222=科主任",
|
|
|
+ "实习医师=实习医师",
|
|
|
+ "国籍=国籍",
|
|
|
+ "工作单位邮政编码=工作单位邮编"
|
|
|
+ );
|
|
|
+
|
|
|
+}
|